replicas-engine 0.1.847 → 0.1.848

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.
@@ -5,11 +5,11 @@ import {
5
5
  getCodexAspHost,
6
6
  restartCodexAspHost,
7
7
  restartCodexAspHostIfRunning
8
- } from "./chunk-PSF3DN47.js";
9
- import "./chunk-HEH6SVCF.js";
10
- import "./chunk-56WIWER6.js";
8
+ } from "./chunk-43SDL344.js";
9
+ import "./chunk-2QWUV5HZ.js";
10
+ import "./chunk-YVEE5YOO.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-MQMKKDOH.js";
12
+ import "./chunk-Q42GPHHD.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
  export {
15
15
  getCodexAspHost,
@@ -15,7 +15,7 @@ import {
15
15
  isValidRelayBaseProvider,
16
16
  parsePosixEnvFile,
17
17
  readReplicasRuntimeEnv
18
- } from "./chunk-MQMKKDOH.js";
18
+ } from "./chunk-Q42GPHHD.js";
19
19
 
20
20
  // src/engine-env.ts
21
21
  import { readFileSync as readFileSync2 } from "fs";
@@ -5,13 +5,13 @@ import {
5
5
  ENGINE_ENV,
6
6
  monolithRequest,
7
7
  setAgentCredentialSnapshot
8
- } from "./chunk-HEH6SVCF.js";
8
+ } from "./chunk-2QWUV5HZ.js";
9
9
  import {
10
10
  AppServerProcess,
11
11
  SUBPROCESS_MAX_BUFFER,
12
12
  buildCodexAgentEnv,
13
13
  execFileAsync
14
- } from "./chunk-56WIWER6.js";
14
+ } from "./chunk-YVEE5YOO.js";
15
15
  import {
16
16
  isRecord
17
17
  } from "./chunk-UZSNFLDQ.js";
@@ -23,7 +23,7 @@ import {
23
23
  createSuccessResult,
24
24
  listOpenAICompatibleModels,
25
25
  resolveOpenAICompatibleModelsUrl
26
- } from "./chunk-MQMKKDOH.js";
26
+ } from "./chunk-Q42GPHHD.js";
27
27
 
28
28
  // src/managers/codex-token-manager.ts
29
29
  import { promises as fs } from "fs";
@@ -49,6 +49,10 @@ function applyAuthEnvTransition(params) {
49
49
  // src/services/credential-fallbacks.ts
50
50
  var fallbacksByAgent = /* @__PURE__ */ new Map();
51
51
  var exhaustedByAgent = /* @__PURE__ */ new Map();
52
+ function clearCredentialFallbacks(provider) {
53
+ fallbacksByAgent.delete(provider);
54
+ exhaustedByAgent.delete(provider);
55
+ }
52
56
  function recordCredentialFallback(notice) {
53
57
  fallbacksByAgent.set(notice.provider, notice);
54
58
  }
@@ -84,9 +88,11 @@ var BaseRefreshManager = class {
84
88
  }
85
89
  managerName;
86
90
  intervalMs;
91
+ credentialGeneration = 0;
92
+ credentialUpdate = Promise.resolve();
87
93
  intervalHandle = null;
88
94
  health;
89
- async start() {
95
+ async start(skipInitialRefresh = false) {
90
96
  if (this.intervalHandle) {
91
97
  return;
92
98
  }
@@ -98,7 +104,7 @@ var BaseRefreshManager = class {
98
104
  console.log(`[${this.managerName}] Starting token refresh service`);
99
105
  this.health.isRunning = true;
100
106
  const config = this.getRuntimeConfig();
101
- if (config) {
107
+ if (config && !skipInitialRefresh) {
102
108
  this.health.lastAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
103
109
  for (let attempt = 1; attempt <= 3; attempt++) {
104
110
  try {
@@ -166,6 +172,15 @@ var BaseRefreshManager = class {
166
172
  getNextRefreshDelayMs() {
167
173
  return this.intervalMs;
168
174
  }
175
+ applyCredentialUpdate(generation, apply) {
176
+ const update = this.credentialUpdate.then(async () => {
177
+ if (generation !== this.credentialGeneration) throw new Error("Credential changed during refresh; retry with the current credential.");
178
+ await apply();
179
+ });
180
+ this.credentialUpdate = update.catch(() => {
181
+ });
182
+ return update;
183
+ }
169
184
  getRuntimeConfig() {
170
185
  if (!ENGINE_ENV.REPLICAS_WORKSPACE_ID) {
171
186
  return null;
@@ -225,7 +240,17 @@ var CodexTokenManager = class extends BaseRefreshManager {
225
240
  async doRefresh(_config) {
226
241
  await this.refreshWithRequest(void 0, true);
227
242
  }
243
+ async switchCredentials(data) {
244
+ await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
245
+ await this.applyCredentialsResponse(data);
246
+ if (data.scope) setAgentCredentialSnapshot("codex", { method: data.type, scope: data.scope, revision: data.revision });
247
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-W2DTK3J5.js");
248
+ await restartCodexAspHostIfRunning2();
249
+ });
250
+ await this.start(true);
251
+ }
228
252
  async refreshWithRequest(request, restartOnChange = false) {
253
+ const generation = this.credentialGeneration;
229
254
  const previousEnv = CODEX_AUTH_ENV_KEYS.map((key) => process.env[key]);
230
255
  console.log("[CodexTokenManager] Refreshing Codex credentials...");
231
256
  const response = await monolithRequest("/v1/engine/codex/refresh-credentials", {
@@ -236,18 +261,20 @@ var CodexTokenManager = class extends BaseRefreshManager {
236
261
  throw new Error(`Credentials refresh failed: ${response.status} ${errorText}`);
237
262
  }
238
263
  const data = await response.json();
239
- await this.applyCredentialsResponse(data);
240
- if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
241
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-TSFKIZ5K.js");
242
- await restartCodexAspHostIfRunning2();
243
- }
244
- if (data.scope) {
245
- setAgentCredentialSnapshot("codex", {
246
- method: data.type,
247
- scope: data.scope,
248
- ...data.revision ? { revision: data.revision } : {}
249
- });
250
- }
264
+ await this.applyCredentialUpdate(generation, async () => {
265
+ await this.applyCredentialsResponse(data);
266
+ if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
267
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-W2DTK3J5.js");
268
+ await restartCodexAspHostIfRunning2();
269
+ }
270
+ if (data.scope) {
271
+ setAgentCredentialSnapshot("codex", {
272
+ method: data.type,
273
+ scope: data.scope,
274
+ ...data.revision ? { revision: data.revision } : {}
275
+ });
276
+ }
277
+ });
251
278
  console.log(`[CodexTokenManager] Credentials refreshed (method=${data.type})`);
252
279
  return data;
253
280
  }
@@ -471,6 +498,7 @@ async function restartCodexAspHostIfRunning() {
471
498
  }
472
499
 
473
500
  export {
501
+ clearCredentialFallbacks,
474
502
  recordCredentialFallback,
475
503
  listCredentialFallbacks,
476
504
  recordExhaustedCredential,
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  shouldRefreshPullRequests
6
- } from "./chunk-MQMKKDOH.js";
6
+ } from "./chunk-Q42GPHHD.js";
7
7
 
8
8
  // src/services/post-tool-pr-notifier.ts
9
9
  async function notifyPostToolUse(toolName, toolInput) {
@@ -631,6 +631,9 @@ var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
631
631
  { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY }
632
632
  ]
633
633
  };
634
+ function agentCredentialMethods(agent) {
635
+ return AGENT_CREDENTIAL_METHODS_IN_ORDER[agent].map((entry) => entry.method);
636
+ }
634
637
  function getCredentialMethodLabel(agent, method) {
635
638
  switch (method) {
636
639
  case CREDENTIAL_METHOD.OAUTH:
@@ -1626,58 +1629,69 @@ function describeAuthFallback(payload) {
1626
1629
  };
1627
1630
  }
1628
1631
 
1632
+ // ../shared/src/workspace-credentials.ts
1633
+ import { z as z5 } from "zod";
1634
+ var WORKSPACE_CREDENTIAL_PROVIDERS = ["claude", "codex"];
1635
+ var workspaceCredentialProviderSchema = z5.enum(WORKSPACE_CREDENTIAL_PROVIDERS);
1636
+ var workspaceCredentialSelectionSchema = agentCredentialSnapshotSchema.omit({ revision: true });
1637
+ var switchWorkspaceCredentialSchema = workspaceCredentialSelectionSchema.extend({
1638
+ provider: workspaceCredentialProviderSchema
1639
+ }).refine(({ provider, method }) => agentCredentialMethods(provider).includes(method), {
1640
+ message: "This authentication method is not supported by this agent"
1641
+ });
1642
+
1629
1643
  // ../shared/src/chat-fork.ts
1630
- import { z as z6 } from "zod";
1644
+ import { z as z7 } from "zod";
1631
1645
 
1632
1646
  // ../shared/src/fallback-chains.ts
1633
- import { z as z5 } from "zod";
1634
- var fallbackHarnessStepSchema = z5.object({
1635
- kind: z5.literal("harness"),
1636
- provider: z5.enum(VALID_AGENT_PROVIDERS),
1637
- relayBaseProvider: z5.enum(VALID_RELAY_BASE_PROVIDERS).optional(),
1638
- model: z5.string().min(1),
1639
- thinkingLevel: z5.enum(VALID_THINKING_LEVELS).optional()
1647
+ import { z as z6 } from "zod";
1648
+ var fallbackHarnessStepSchema = z6.object({
1649
+ kind: z6.literal("harness"),
1650
+ provider: z6.enum(VALID_AGENT_PROVIDERS),
1651
+ relayBaseProvider: z6.enum(VALID_RELAY_BASE_PROVIDERS).optional(),
1652
+ model: z6.string().min(1),
1653
+ thinkingLevel: z6.enum(VALID_THINKING_LEVELS).optional()
1640
1654
  });
1641
- var fallbackPlanStepSchema = z5.discriminatedUnion("kind", [
1642
- z5.object({ kind: z5.literal("credentials"), methods: z5.array(z5.custom(isAuthMethod)).min(1) }),
1655
+ var fallbackPlanStepSchema = z6.discriminatedUnion("kind", [
1656
+ z6.object({ kind: z6.literal("credentials"), methods: z6.array(z6.custom(isAuthMethod)).min(1) }),
1643
1657
  fallbackHarnessStepSchema
1644
1658
  ]);
1645
- var fallbackPlanResponseSchema = z5.object({ steps: z5.array(fallbackPlanStepSchema) });
1659
+ var fallbackPlanResponseSchema = z6.object({ steps: z6.array(fallbackPlanStepSchema) });
1646
1660
 
1647
1661
  // ../shared/src/chat-fork.ts
1648
- var quotaLimitKindSchema = z6.enum(["rate_limit", "out_of_credits"]);
1649
- var chatForkInfoSchema = z6.object({
1650
- source: z6.object({
1651
- chatId: z6.string().min(1),
1652
- provider: z6.enum(VALID_AGENT_PROVIDERS),
1653
- title: z6.string()
1662
+ var quotaLimitKindSchema = z7.enum(["rate_limit", "out_of_credits"]);
1663
+ var chatForkInfoSchema = z7.object({
1664
+ source: z7.object({
1665
+ chatId: z7.string().min(1),
1666
+ provider: z7.enum(VALID_AGENT_PROVIDERS),
1667
+ title: z7.string()
1654
1668
  }),
1655
- trigger: z6.enum(["manual", "auto"]),
1669
+ trigger: z7.enum(["manual", "auto"]),
1656
1670
  reason: quotaLimitKindSchema.optional(),
1657
- state: z6.enum(["preparing", "ready", "failed"]),
1658
- error: z6.string().optional(),
1659
- startedAt: z6.string(),
1660
- completedAt: z6.string().optional()
1671
+ state: z7.enum(["preparing", "ready", "failed"]),
1672
+ error: z7.string().optional(),
1673
+ startedAt: z7.string(),
1674
+ completedAt: z7.string().optional()
1661
1675
  });
1662
1676
  function coerceChatForkInfo(value) {
1663
1677
  const parsed = chatForkInfoSchema.safeParse(value);
1664
1678
  return parsed.success ? parsed.data : null;
1665
1679
  }
1666
- var forkChatRequestSchema = z6.object({
1667
- provider: z6.enum(VALID_AGENT_PROVIDERS),
1668
- relayBaseProvider: z6.enum(VALID_RELAY_BASE_PROVIDERS).optional(),
1669
- model: z6.string().min(1).optional(),
1670
- thinkingLevel: z6.enum(VALID_THINKING_LEVELS).optional(),
1671
- title: z6.string().min(1).max(200).optional(),
1672
- message: z6.string().trim().optional(),
1673
- id: z6.string().uuid().optional(),
1674
- clientRequestId: z6.string().min(1).max(128).optional(),
1675
- enableInteractiveTools: z6.boolean().optional(),
1680
+ var forkChatRequestSchema = z7.object({
1681
+ provider: z7.enum(VALID_AGENT_PROVIDERS),
1682
+ relayBaseProvider: z7.enum(VALID_RELAY_BASE_PROVIDERS).optional(),
1683
+ model: z7.string().min(1).optional(),
1684
+ thinkingLevel: z7.enum(VALID_THINKING_LEVELS).optional(),
1685
+ title: z7.string().min(1).max(200).optional(),
1686
+ message: z7.string().trim().optional(),
1687
+ id: z7.string().uuid().optional(),
1688
+ clientRequestId: z7.string().min(1).max(128).optional(),
1689
+ enableInteractiveTools: z7.boolean().optional(),
1676
1690
  // Server-injected by the monolith from the authenticated request; never trusted from clients.
1677
- senderUserId: z6.string().optional(),
1678
- senderEmail: z6.string().optional(),
1679
- senderDisplayName: z6.string().optional(),
1680
- senderAvatarUrl: z6.string().optional()
1691
+ senderUserId: z7.string().optional(),
1692
+ senderEmail: z7.string().optional(),
1693
+ senderDisplayName: z7.string().optional(),
1694
+ senderAvatarUrl: z7.string().optional()
1681
1695
  });
1682
1696
  function describeQuotaLimit(reason) {
1683
1697
  return reason === "out_of_credits" ? "ran out of credits" : "hit its usage limit";
@@ -1686,10 +1700,10 @@ function describeChatForkReason(reason, provider) {
1686
1700
  return reason ? `${getProviderDisplayName(provider)} ${describeQuotaLimit(reason)}` : null;
1687
1701
  }
1688
1702
  var AGENT_QUOTA_EXHAUSTED_EVENT_TYPE = "agent-quota-exhausted";
1689
- var agentQuotaExhaustedPayloadSchema = z6.object({
1690
- provider: z6.enum(VALID_CODING_AGENT_PROVIDERS),
1703
+ var agentQuotaExhaustedPayloadSchema = z7.object({
1704
+ provider: z7.enum(VALID_CODING_AGENT_PROVIDERS),
1691
1705
  reason: quotaLimitKindSchema,
1692
- detail: z6.string().optional(),
1706
+ detail: z7.string().optional(),
1693
1707
  forkTo: fallbackHarnessStepSchema.optional()
1694
1708
  });
1695
1709
  function defaultForkChatTitle(source, provider) {
@@ -2954,32 +2968,32 @@ var MEDIA_ABILITY = {
2954
2968
  };
2955
2969
 
2956
2970
  // ../shared/src/memory.ts
2957
- import { z as z7 } from "zod";
2971
+ import { z as z8 } from "zod";
2958
2972
  var MEMORY_ROOT = `${SANDBOX_PATHS.REPLICAS_DIR}/memories`;
2959
2973
  var MEMORY_INDEX_FILENAME = "MEMORY.md";
2960
2974
  var MEMORY_BUNDLE_FILENAME = "memory.tar.gz";
2961
2975
  var MEMORY_MARKER_GUIDANCE = `When you decide that a preference, correction, decision, procedure, or lesson is worth remembering for future sessions, say so in your response casually, like a coworker: "Ah, I'll remember that for next time" or "I'll keep that in mind." Keep it natural and never mention the memory feature, memory pipeline, markers, persistence, or that you are saving or adding something to memory. These phrases signal intent to remember; they do not mean anything has already been saved, so do not claim persistence is complete.`;
2962
- var memoryExtractionResultSchema = z7.object({
2963
- seatSummary: z7.string().nullable(),
2964
- organizationSummary: z7.string().nullable()
2976
+ var memoryExtractionResultSchema = z8.object({
2977
+ seatSummary: z8.string().nullable(),
2978
+ organizationSummary: z8.string().nullable()
2965
2979
  });
2966
- var { $schema: _, ...MEMORY_EXTRACTION_SCHEMA } = z7.toJSONSchema(memoryExtractionResultSchema);
2967
- var memoryGenerationManifestSchema = z7.object({
2968
- domainId: z7.string(),
2969
- generation: z7.number().int().nonnegative(),
2970
- previousManifestKey: z7.string().nullable(),
2971
- createdAt: z7.string(),
2972
- promptVersion: z7.string(),
2973
- harness: z7.enum(["claude", "codex", "none"]),
2974
- model: z7.string(),
2975
- bundle: z7.object({
2976
- path: z7.literal(MEMORY_BUNDLE_FILENAME),
2977
- sha256: z7.string().regex(/^[a-f0-9]{64}$/),
2978
- sizeBytes: z7.number().int().positive()
2980
+ var { $schema: _, ...MEMORY_EXTRACTION_SCHEMA } = z8.toJSONSchema(memoryExtractionResultSchema);
2981
+ var memoryGenerationManifestSchema = z8.object({
2982
+ domainId: z8.string(),
2983
+ generation: z8.number().int().nonnegative(),
2984
+ previousManifestKey: z8.string().nullable(),
2985
+ createdAt: z8.string(),
2986
+ promptVersion: z8.string(),
2987
+ harness: z8.enum(["claude", "codex", "none"]),
2988
+ model: z8.string(),
2989
+ bundle: z8.object({
2990
+ path: z8.literal(MEMORY_BUNDLE_FILENAME),
2991
+ sha256: z8.string().regex(/^[a-f0-9]{64}$/),
2992
+ sizeBytes: z8.number().int().positive()
2979
2993
  }).nullable(),
2980
- files: z7.record(z7.string(), z7.string()),
2981
- rollouts: z7.record(z7.string(), z7.string()),
2982
- rolloutSources: z7.record(z7.string(), z7.string()).optional()
2994
+ files: z8.record(z8.string(), z8.string()),
2995
+ rollouts: z8.record(z8.string(), z8.string()),
2996
+ rolloutSources: z8.record(z8.string(), z8.string()).optional()
2983
2997
  });
2984
2998
 
2985
2999
  // ../shared/src/default-skills/replicas-agent/abilities/memory.ts
@@ -7435,46 +7449,46 @@ var DEFAULT_WORKSPACE_FILTERS = {
7435
7449
  var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
7436
7450
 
7437
7451
  // ../shared/src/routes/workspace-events.ts
7438
- import { z as z8 } from "zod";
7439
- var workspaceChangedEventSchema = z8.discriminatedUnion("type", [
7440
- z8.object({
7441
- type: z8.literal("workspace.changed"),
7442
- workspaceId: z8.string(),
7443
- completion: z8.object({
7444
- workspaceName: z8.string(),
7445
- completedAt: z8.string(),
7446
- processing: z8.boolean().optional()
7452
+ import { z as z9 } from "zod";
7453
+ var workspaceChangedEventSchema = z9.discriminatedUnion("type", [
7454
+ z9.object({
7455
+ type: z9.literal("workspace.changed"),
7456
+ workspaceId: z9.string(),
7457
+ completion: z9.object({
7458
+ workspaceName: z9.string(),
7459
+ completedAt: z9.string(),
7460
+ processing: z9.boolean().optional()
7447
7461
  }).optional(),
7448
- ts: z8.string()
7462
+ ts: z9.string()
7449
7463
  }),
7450
- z8.object({
7451
- type: z8.literal("workspace.chat.changed"),
7452
- workspaceId: z8.string(),
7453
- chatId: z8.string(),
7454
- ts: z8.string()
7464
+ z9.object({
7465
+ type: z9.literal("workspace.chat.changed"),
7466
+ workspaceId: z9.string(),
7467
+ chatId: z9.string(),
7468
+ ts: z9.string()
7455
7469
  }),
7456
- z8.object({ type: z8.literal("presence.changed"), ts: z8.string() }),
7457
- z8.object({
7458
- type: z8.literal("mobile-testing.changed"),
7459
- workspaceId: z8.string(),
7460
- ts: z8.string()
7470
+ z9.object({ type: z9.literal("presence.changed"), ts: z9.string() }),
7471
+ z9.object({
7472
+ type: z9.literal("mobile-testing.changed"),
7473
+ workspaceId: z9.string(),
7474
+ ts: z9.string()
7461
7475
  })
7462
7476
  ]);
7463
7477
 
7464
7478
  // ../shared/src/routes/presence.ts
7465
- import { z as z9 } from "zod";
7466
- var presenceStatusSchema = z9.enum(["online", "typing"]);
7467
- var presenceLocationSchema = z9.object({
7468
- environmentId: z9.string().optional(),
7469
- workspaceId: z9.string().optional()
7479
+ import { z as z10 } from "zod";
7480
+ var presenceStatusSchema = z10.enum(["online", "typing"]);
7481
+ var presenceLocationSchema = z10.object({
7482
+ environmentId: z10.string().optional(),
7483
+ workspaceId: z10.string().optional()
7470
7484
  });
7471
- var presenceEntrySchema = z9.object({
7472
- userId: z9.string(),
7485
+ var presenceEntrySchema = z10.object({
7486
+ userId: z10.string(),
7473
7487
  status: presenceStatusSchema,
7474
7488
  location: presenceLocationSchema,
7475
- ts: z9.string()
7489
+ ts: z10.string()
7476
7490
  });
7477
- var updatePresenceRequestSchema = z9.object({
7491
+ var updatePresenceRequestSchema = z10.object({
7478
7492
  status: presenceStatusSchema,
7479
7493
  location: presenceLocationSchema.optional()
7480
7494
  });
@@ -7839,6 +7853,7 @@ export {
7839
7853
  TOKEN_USAGE_PATH,
7840
7854
  isTokenUsageCounts,
7841
7855
  isTokenUsageUploadRecord,
7856
+ workspaceCredentialProviderSchema,
7842
7857
  fallbackPlanResponseSchema,
7843
7858
  ASTER_PROVIDER,
7844
7859
  ASTER_BASE_URL,
@@ -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-HEH6SVCF.js";
6
+ } from "./chunk-2QWUV5HZ.js";
7
7
  import {
8
8
  extractCommandProtectionCommandText,
9
9
  findGitCommitSignals,
10
10
  findPrMergeSignals
11
- } from "./chunk-MQMKKDOH.js";
11
+ } from "./chunk-Q42GPHHD.js";
12
12
 
13
13
  // src/services/command-protection-service.ts
14
14
  var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
@@ -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-MQMKKDOH.js";
7
+ } from "./chunk-Q42GPHHD.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.847";
244
+ var ENGINE_PACKAGE_VERSION = "0.1.848";
245
245
  var INITIALIZE_METHOD = "initialize";
246
246
  var INITIALIZED_NOTIFICATION = "initialized";
247
247
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -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-T32XK5XV.js";
7
- import "./chunk-HEH6SVCF.js";
6
+ } from "./chunk-RLNQ34YJ.js";
7
+ import "./chunk-2QWUV5HZ.js";
8
8
  import {
9
9
  isRecord
10
10
  } from "./chunk-UZSNFLDQ.js";
11
- import "./chunk-MQMKKDOH.js";
11
+ import "./chunk-Q42GPHHD.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-T32XK5XV.js";
6
+ } from "./chunk-RLNQ34YJ.js";
7
7
  import {
8
8
  notifyPostToolUse
9
- } from "./chunk-LZSQ7376.js";
10
- import "./chunk-HEH6SVCF.js";
9
+ } from "./chunk-CGN7NMUB.js";
10
+ import "./chunk-2QWUV5HZ.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-MQMKKDOH.js";
12
+ import "./chunk-Q42GPHHD.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-56WIWER6.js";
11
+ } from "./chunk-YVEE5YOO.js";
12
12
  import {
13
13
  AGENT,
14
14
  getMemoryOutputSafetyViolation,
15
15
  headlessAgentRequestSchema
16
- } from "./chunk-MQMKKDOH.js";
16
+ } from "./chunk-Q42GPHHD.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-T32XK5XV.js";
94
+ } from "./chunk-RLNQ34YJ.js";
95
95
  import {
96
96
  ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
97
97
  AGENT_MESSAGE_DELTA_METHOD,
@@ -125,26 +125,27 @@ import {
125
125
  BaseRefreshManager,
126
126
  CodexAspAuthMethodChangedError,
127
127
  applyAuthEnvTransition,
128
+ clearCredentialFallbacks,
128
129
  codexTokenManager,
129
130
  getCodexAspHost,
130
131
  listCredentialFallbacks,
131
132
  recordCredentialFallback,
132
133
  recordExhaustedCredential,
133
134
  restartCodexAspHost
134
- } from "./chunk-PSF3DN47.js";
135
+ } from "./chunk-43SDL344.js";
135
136
  import {
136
137
  ENGINE_ENV,
137
138
  IS_WARMING_MODE,
138
139
  monolithRequest,
139
140
  monolithService,
140
141
  setAgentCredentialSnapshot
141
- } from "./chunk-HEH6SVCF.js";
142
+ } from "./chunk-2QWUV5HZ.js";
142
143
  import {
143
144
  AspClient,
144
145
  SUBPROCESS_MAX_BUFFER,
145
146
  execAsync,
146
147
  execFileAsync
147
- } from "./chunk-56WIWER6.js";
148
+ } from "./chunk-YVEE5YOO.js";
148
149
  import {
149
150
  isRecord as isRecord2
150
151
  } from "./chunk-UZSNFLDQ.js";
@@ -354,8 +355,9 @@ import {
354
355
  shouldRefreshPullRequests,
355
356
  spawnRelaySubagentRequestSchema,
356
357
  stripAgentDiagnosticErrors,
357
- withTimeout
358
- } from "./chunk-MQMKKDOH.js";
358
+ withTimeout,
359
+ workspaceCredentialProviderSchema
360
+ } from "./chunk-Q42GPHHD.js";
359
361
  import {
360
362
  __commonJS,
361
363
  __export,
@@ -9427,7 +9429,12 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
9427
9429
  async doRefresh(_config) {
9428
9430
  await this.refreshWithRequest();
9429
9431
  }
9432
+ async switchCredentials(data) {
9433
+ await this.applyCredentialUpdate(++this.credentialGeneration, () => this.applyCredentialsResponse(data));
9434
+ await this.start(true);
9435
+ }
9430
9436
  async refreshWithRequest(request) {
9437
+ const generation = this.credentialGeneration;
9431
9438
  console.log("[ClaudeTokenManager] Refreshing Claude credentials...");
9432
9439
  const response = await monolithRequest("/v1/engine/claude/refresh-credentials", {
9433
9440
  body: request
@@ -9437,14 +9444,7 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
9437
9444
  throw new Error(`Credentials refresh failed: ${response.status} ${errorText}`);
9438
9445
  }
9439
9446
  const data = await response.json();
9440
- await this.applyCredentialsResponse(data);
9441
- if (data.scope) {
9442
- setAgentCredentialSnapshot("claude", {
9443
- method: data.type,
9444
- scope: data.scope,
9445
- ...data.revision ? { revision: data.revision } : {}
9446
- });
9447
- }
9447
+ await this.applyCredentialUpdate(generation, () => this.applyCredentialsResponse(data));
9448
9448
  console.log(`[ClaudeTokenManager] Credentials refreshed (method=${data.type})`);
9449
9449
  }
9450
9450
  async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.claude, allowedMethods) {
@@ -9484,6 +9484,13 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
9484
9484
  newEnvVars: envVars,
9485
9485
  envs: [ENGINE_ENV, process.env]
9486
9486
  });
9487
+ if (response.scope) {
9488
+ setAgentCredentialSnapshot("claude", {
9489
+ method: response.type,
9490
+ scope: response.scope,
9491
+ ...response.revision ? { revision: response.revision } : {}
9492
+ });
9493
+ }
9487
9494
  }
9488
9495
  async writeOauthCredentialsFile(credentials) {
9489
9496
  const credentialsPath = path3.join(ENGINE_ENV.HOME_DIR, ".claude", ".credentials.json");
@@ -9505,14 +9512,12 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
9505
9512
  console.log(`[ClaudeTokenManager] Updated ${credentialsPath}`);
9506
9513
  } catch (error) {
9507
9514
  console.error("[ClaudeTokenManager] Failed to update credentials file:", error);
9515
+ throw error;
9508
9516
  }
9509
9517
  }
9510
9518
  async removeOauthCredentialsFile() {
9511
9519
  const credentialsPath = path3.join(ENGINE_ENV.HOME_DIR, ".claude", ".credentials.json");
9512
- try {
9513
- await fs.unlink(credentialsPath);
9514
- } catch {
9515
- }
9520
+ await fs.rm(credentialsPath, { force: true });
9516
9521
  }
9517
9522
  };
9518
9523
  var claudeTokenManager = new ClaudeTokenManager();
@@ -9928,6 +9933,8 @@ var EnvironmentDetailsService = class {
9928
9933
  details.supportsQueuedMessageEditing = true;
9929
9934
  details.supportsChatForking = true;
9930
9935
  details.supportsChatForkMessage = true;
9936
+ details.supportsCredentialSwitching = true;
9937
+ details.agentCredentials = { ...ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS };
9931
9938
  details.claudeAuthMethod = detectAgentAuthMethod(AGENT.CLAUDE);
9932
9939
  details.codexAuthMethod = detectAgentAuthMethod(AGENT.CODEX);
9933
9940
  details.cursorAuthMethod = detectAgentAuthMethod(AGENT.CURSOR);
@@ -12838,7 +12845,6 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
12838
12845
  activePromptStream = null;
12839
12846
  activeSessionSignature = null;
12840
12847
  activeSessionModel = null;
12841
- activeSessionPermissionMode = null;
12842
12848
  sessionLoop = null;
12843
12849
  sessionLinearForwarder = null;
12844
12850
  pendingTurn = null;
@@ -13327,13 +13333,12 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13327
13333
  const resolvedPermissionMode = planMode ? "plan" : "bypassPermissions";
13328
13334
  const resolvedFastMode = Boolean(fastMode && canUseClaudeFastMode(resolvedModel));
13329
13335
  const signature = {
13336
+ credential: JSON.stringify(ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.claude),
13330
13337
  combinedInstructions,
13331
13338
  thinkingLevel,
13332
- // enableInteractiveTools only matters in plan mode; the session signature
13333
- // tracks the effective flag so a mode change can hot-swap via setPermissionMode
13334
- // without restarting.
13335
13339
  enableInteractiveTools: Boolean(enableInteractiveTools),
13336
- fastMode: resolvedFastMode
13340
+ fastMode: resolvedFastMode,
13341
+ permissionMode: resolvedPermissionMode
13337
13342
  };
13338
13343
  await this.ensureSession({
13339
13344
  signature,
@@ -13378,15 +13383,6 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13378
13383
  await this.tearDownSession();
13379
13384
  }
13380
13385
  }
13381
- if (this.activeQuery && this.activeSessionPermissionMode !== resolvedPermissionMode) {
13382
- try {
13383
- await this.activeQuery.setPermissionMode(resolvedPermissionMode);
13384
- this.activeSessionPermissionMode = resolvedPermissionMode;
13385
- } catch (err) {
13386
- console.warn("[ClaudeManager] setPermissionMode failed; recreating session:", err);
13387
- await this.tearDownSession();
13388
- }
13389
- }
13390
13386
  if (this.activeQuery) return;
13391
13387
  } else if (this.activeQuery) {
13392
13388
  await this.tearDownSession();
@@ -13402,7 +13398,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13402
13398
  });
13403
13399
  }
13404
13400
  sessionSignaturesMatch(a, b) {
13405
- return a.combinedInstructions === b.combinedInstructions && a.thinkingLevel === b.thinkingLevel && a.enableInteractiveTools === b.enableInteractiveTools && a.fastMode === b.fastMode;
13401
+ return a.combinedInstructions === b.combinedInstructions && a.credential === b.credential && a.thinkingLevel === b.thinkingLevel && a.enableInteractiveTools === b.enableInteractiveTools && a.fastMode === b.fastMode && a.permissionMode === b.permissionMode;
13406
13402
  }
13407
13403
  /** Query inputs shared by real sessions and slash-command discovery. */
13408
13404
  async buildSharedQueryOptions() {
@@ -13474,7 +13470,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13474
13470
  forwardSubagentText: true,
13475
13471
  ...supportsClaudeThinkingDisplay(resolvedModel) ? { thinking: { type: "adaptive", display: "summarized" } } : {},
13476
13472
  ...effort ? { effort } : {},
13477
- canUseTool: this.buildCanUseTool(),
13473
+ ...resolvedPermissionMode === "plan" ? { canUseTool: this.buildCanUseTool() } : {},
13478
13474
  hooks: {
13479
13475
  PreToolUse: [{
13480
13476
  matcher: "*",
@@ -13509,7 +13505,6 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13509
13505
  this.activePromptStream = promptStream;
13510
13506
  this.activeSessionSignature = signature;
13511
13507
  this.activeSessionModel = claudeCodeModel;
13512
- this.activeSessionPermissionMode = resolvedPermissionMode;
13513
13508
  this.sessionLinearForwarder = new LinearEventForwarder(ENGINE_ENV.REPLICAS_LINEAR_SESSION_ID);
13514
13509
  this.sessionLoop = this.runSessionLoop(response).catch((err) => {
13515
13510
  console.error("[ClaudeManager] Session loop crashed:", err);
@@ -13634,7 +13629,6 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13634
13629
  this.activePromptStream = null;
13635
13630
  this.activeSessionSignature = null;
13636
13631
  this.activeSessionModel = null;
13637
- this.activeSessionPermissionMode = null;
13638
13632
  this.sessionLinearForwarder = null;
13639
13633
  this.sessionLoop = null;
13640
13634
  this.clearBackgroundContinuationTimer();
@@ -61728,6 +61722,9 @@ var ChatService = class {
61728
61722
  listChats(includeChildren = false) {
61729
61723
  return Array.from(this.chats.values()).filter((chat) => !chat.persisted.deletedAt && (includeChildren || chat.persisted.parentChatId === null)).map((chat) => this.toSummary(chat)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
61730
61724
  }
61725
+ hasActiveAgentWork(provider) {
61726
+ return [...this.chats.values()].some((chat) => getChatExecutionProvider(chat.persisted) === provider && (chat.provider.isProcessing() || chat.acceptingMessages > 0 || chat.pendingMessageIds.length > 0));
61727
+ }
61731
61728
  listDeletedChats() {
61732
61729
  return Array.from(this.chats.values()).filter((chat) => chat.persisted.deletedAt && chat.persisted.parentChatId === null).map((chat) => this.toSummary(chat)).sort((a, b) => (b.deletedAt ?? "").localeCompare(a.deletedAt ?? ""));
61733
61730
  }
@@ -64521,6 +64518,18 @@ data: ${JSON.stringify("Terminal session not found")}
64521
64518
  );
64522
64519
  }
64523
64520
  });
64521
+ app2.post("/credentials/switch", async (c) => {
64522
+ const body = await c.req.json();
64523
+ const provider = workspaceCredentialProviderSchema.safeParse(body.provider);
64524
+ if (!provider.success) return c.json(jsonError("Unsupported agent"), 400);
64525
+ if (deps.chatService.hasActiveAgentWork(provider.data)) {
64526
+ return c.json(jsonError("Stop this agent\u2019s running chats and clear their queues before switching credentials."), 409);
64527
+ }
64528
+ if (body.provider === "codex") await codexTokenManager.switchCredentials(body.credential);
64529
+ else await claudeTokenManager.switchCredentials(body.credential);
64530
+ clearCredentialFallbacks(provider.data);
64531
+ return c.json(await environmentDetailsService.getDetails());
64532
+ });
64524
64533
  app2.post("/codex/refresh-now", async (c) => {
64525
64534
  try {
64526
64535
  const result = await codexTokenManager.refreshOnce(true);
@@ -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-LZSQ7376.js";
6
+ } from "./chunk-CGN7NMUB.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
- import "./chunk-MQMKKDOH.js";
10
+ import "./chunk-Q42GPHHD.js";
11
11
  import "./chunk-VEQXQN22.js";
12
12
 
13
13
  // src/post-tool-pr-hook.ts
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  messageRelaySubagentRequestSchema,
9
9
  spawnRelaySubagentRequestSchema
10
- } from "./chunk-MQMKKDOH.js";
10
+ } from "./chunk-Q42GPHHD.js";
11
11
  import "./chunk-VEQXQN22.js";
12
12
 
13
13
  // src/relay-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.847",
3
+ "version": "0.1.848",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",