replicas-engine 0.1.1035 → 0.1.1037

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,7 +5,7 @@ import {
5
5
  extractCommandProtectionCommandText,
6
6
  isRecord,
7
7
  parseCodeHostPrUrl
8
- } from "./chunk-MD2DJUY2.js";
8
+ } from "./chunk-KKQJOAN5.js";
9
9
 
10
10
  // src/services/published-pull-request-urls.ts
11
11
  function publishedPullRequestUrls(result) {
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
+ import {
5
+ SUBPROCESS_MAX_BUFFER,
6
+ execFileAsync
7
+ } from "./chunk-2OZUYL37.js";
4
8
  import {
5
9
  isRecord as isRecord2
6
10
  } from "./chunk-UZSNFLDQ.js";
@@ -14,7 +18,7 @@ import {
14
18
  isValidAgentProvider,
15
19
  parsePosixEnvFile,
16
20
  readReplicasRuntimeEnv
17
- } from "./chunk-MD2DJUY2.js";
21
+ } from "./chunk-KKQJOAN5.js";
18
22
 
19
23
  // src/runtime-env-loader.ts
20
24
  import { readFileSync } from "fs";
@@ -176,6 +180,82 @@ function setAgentCredentialSnapshot(provider, { type, scope, revision, account,
176
180
  process.env.REPLICAS_AGENT_CREDENTIALS = JSON.stringify(ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS);
177
181
  }
178
182
 
183
+ // src/git/commands.ts
184
+ import { readdirSync, readFileSync as readFileSync3, statSync } from "fs";
185
+ import { join as join3, resolve } from "path";
186
+ async function runGitCommand(args, cwd, options = {}) {
187
+ const { stdout } = await execFileAsync("git", args, {
188
+ cwd,
189
+ encoding: "utf-8",
190
+ maxBuffer: options.maxBuffer ?? SUBPROCESS_MAX_BUFFER
191
+ });
192
+ return stdout.trim();
193
+ }
194
+ function readRepoHeadBranches(repoPath) {
195
+ const branches = /* @__PURE__ */ new Set();
196
+ try {
197
+ let gitDir = join3(repoPath, ".git");
198
+ if (statSync(gitDir).isFile()) {
199
+ const target = readFileSync3(gitDir, "utf8").trim().match(/^gitdir: (.+)$/)?.[1];
200
+ if (!target) return branches;
201
+ gitDir = resolve(repoPath, target);
202
+ }
203
+ let commonDir = gitDir;
204
+ try {
205
+ commonDir = resolve(gitDir, readFileSync3(join3(gitDir, "commondir"), "utf8").trim());
206
+ } catch {
207
+ }
208
+ const headDirs = /* @__PURE__ */ new Set([gitDir, commonDir]);
209
+ try {
210
+ for (const entry of readdirSync(join3(commonDir, "worktrees"))) {
211
+ headDirs.add(join3(commonDir, "worktrees", entry));
212
+ }
213
+ } catch {
214
+ }
215
+ for (const dir of headDirs) {
216
+ try {
217
+ const branch = readFileSync3(join3(dir, "HEAD"), "utf8").trim().match(/^ref:\s+refs\/heads\/(.+)$/)?.[1];
218
+ if (branch) branches.add(branch);
219
+ } catch {
220
+ }
221
+ }
222
+ } catch {
223
+ }
224
+ return branches;
225
+ }
226
+ async function branchExists(branchName, cwd) {
227
+ try {
228
+ await runGitCommand(["rev-parse", "--verify", branchName], cwd);
229
+ return true;
230
+ } catch {
231
+ return false;
232
+ }
233
+ }
234
+ async function getOriginDefaultBranch(repoPath) {
235
+ try {
236
+ const output = await runGitCommand(["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], repoPath);
237
+ return output.match(/^origin\/(.+)$/)?.[1] ?? null;
238
+ } catch {
239
+ return null;
240
+ }
241
+ }
242
+ async function getCurrentBranch(cwd) {
243
+ try {
244
+ return await runGitCommand(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
245
+ } catch (error) {
246
+ console.error("Error getting current branch:", error);
247
+ return null;
248
+ }
249
+ }
250
+ async function resolveDiffBase(repoPath, defaultBranch) {
251
+ const baseBranch = `origin/${defaultBranch}`;
252
+ try {
253
+ return await runGitCommand(["merge-base", baseBranch, "HEAD"], repoPath);
254
+ } catch {
255
+ }
256
+ return await branchExists(baseBranch, repoPath) ? baseBranch : "HEAD";
257
+ }
258
+
179
259
  // src/services/monolith-service.ts
180
260
  async function monolithRequest(path, init = {}) {
181
261
  if (!ENGINE_ENV.REPLICAS_WORKSPACE_ID) {
@@ -251,6 +331,11 @@ var MonolithService = class {
251
331
  var monolithService = new MonolithService();
252
332
 
253
333
  export {
334
+ runGitCommand,
335
+ readRepoHeadBranches,
336
+ getOriginDefaultBranch,
337
+ getCurrentBranch,
338
+ resolveDiffBase,
254
339
  readRuntimeEnvFile,
255
340
  ENGINE_ENV,
256
341
  reloadEngineEnv,
@@ -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-SEYXPQY7.js";
6
+ } from "./chunk-2OZUYL37.js";
7
7
  import {
8
8
  isVersionBelow
9
- } from "./chunk-MD2DJUY2.js";
9
+ } from "./chunk-KKQJOAN5.js";
10
10
 
11
11
  // src/utils/codex-agent-env.ts
12
12
  function buildCodexAgentEnv(source = process.env) {
@@ -233,14 +233,14 @@ var DEFAULT_CODEX_ARGS = [
233
233
  "-c",
234
234
  "memories.generate_memories=false"
235
235
  ];
236
- var MIN_CODEX_CLI_VERSION = "0.159.2";
236
+ var MIN_CODEX_CLI_VERSION = "0.162.1";
237
237
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
238
238
  var codexCliVersionEnsured = null;
239
239
  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.1035";
243
+ var ENGINE_PACKAGE_VERSION = "0.1.1037";
244
244
  var INITIALIZE_METHOD = "initialize";
245
245
  var INITIALIZED_NOTIFICATION = "initialized";
246
246
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -2,100 +2,20 @@
2
2
  import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
- monolithRequest
6
- } from "./chunk-WRAVQEOB.js";
7
- import {
8
- SUBPROCESS_MAX_BUFFER,
9
- execFileAsync
10
- } from "./chunk-SEYXPQY7.js";
5
+ getOriginDefaultBranch,
6
+ monolithRequest,
7
+ runGitCommand
8
+ } from "./chunk-BPPOGNJ5.js";
11
9
  import {
12
10
  extractCommandProtectionCommandText,
13
11
  findCommandProtectionGitLookups,
14
12
  findGitCommitSignals,
15
13
  findPrMergeSignals,
16
14
  parseCommandProtectionRequest
17
- } from "./chunk-MD2DJUY2.js";
15
+ } from "./chunk-KKQJOAN5.js";
18
16
 
19
17
  // src/services/command-protection-service.ts
20
18
  import { readFile, stat } from "fs/promises";
21
-
22
- // src/git/commands.ts
23
- import { readdirSync, readFileSync, statSync } from "fs";
24
- import { join, resolve } from "path";
25
- async function runGitCommand(args, cwd, options = {}) {
26
- const { stdout } = await execFileAsync("git", args, {
27
- cwd,
28
- encoding: "utf-8",
29
- maxBuffer: options.maxBuffer ?? SUBPROCESS_MAX_BUFFER
30
- });
31
- return stdout.trim();
32
- }
33
- function readRepoHeadBranches(repoPath) {
34
- const branches = /* @__PURE__ */ new Set();
35
- try {
36
- let gitDir = join(repoPath, ".git");
37
- if (statSync(gitDir).isFile()) {
38
- const target = readFileSync(gitDir, "utf8").trim().match(/^gitdir: (.+)$/)?.[1];
39
- if (!target) return branches;
40
- gitDir = resolve(repoPath, target);
41
- }
42
- let commonDir = gitDir;
43
- try {
44
- commonDir = resolve(gitDir, readFileSync(join(gitDir, "commondir"), "utf8").trim());
45
- } catch {
46
- }
47
- const headDirs = /* @__PURE__ */ new Set([gitDir, commonDir]);
48
- try {
49
- for (const entry of readdirSync(join(commonDir, "worktrees"))) {
50
- headDirs.add(join(commonDir, "worktrees", entry));
51
- }
52
- } catch {
53
- }
54
- for (const dir of headDirs) {
55
- try {
56
- const branch = readFileSync(join(dir, "HEAD"), "utf8").trim().match(/^ref:\s+refs\/heads\/(.+)$/)?.[1];
57
- if (branch) branches.add(branch);
58
- } catch {
59
- }
60
- }
61
- } catch {
62
- }
63
- return branches;
64
- }
65
- async function branchExists(branchName, cwd) {
66
- try {
67
- await runGitCommand(["rev-parse", "--verify", branchName], cwd);
68
- return true;
69
- } catch {
70
- return false;
71
- }
72
- }
73
- async function getOriginDefaultBranch(repoPath) {
74
- try {
75
- const output = await runGitCommand(["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], repoPath);
76
- return output.match(/^origin\/(.+)$/)?.[1] ?? null;
77
- } catch {
78
- return null;
79
- }
80
- }
81
- async function getCurrentBranch(cwd) {
82
- try {
83
- return await runGitCommand(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
84
- } catch (error) {
85
- console.error("Error getting current branch:", error);
86
- return null;
87
- }
88
- }
89
- async function resolveDiffBase(repoPath, defaultBranch) {
90
- const baseBranch = `origin/${defaultBranch}`;
91
- try {
92
- return await runGitCommand(["merge-base", baseBranch, "HEAD"], repoPath);
93
- } catch {
94
- }
95
- return await branchExists(baseBranch, repoPath) ? baseBranch : "HEAD";
96
- }
97
-
98
- // src/services/command-protection-service.ts
99
19
  var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
100
20
  var MAX_COMMIT_MESSAGE_FILE_BYTES = 64 * 1024;
101
21
  async function resolveGitContext({ repoDirs, messageFiles }) {
@@ -180,11 +100,6 @@ function reportCommandProtectionBlock(options) {
180
100
  }
181
101
 
182
102
  export {
183
- runGitCommand,
184
- readRepoHeadBranches,
185
- getOriginDefaultBranch,
186
- getCurrentBranch,
187
- resolveDiffBase,
188
103
  evaluateCommandProtection,
189
104
  extractToolCommand,
190
105
  reportCommandProtectionBlock
@@ -10,6 +10,31 @@ function isNonEmptyString(value) {
10
10
  return typeof value === "string" && value.trim().length > 0;
11
11
  }
12
12
 
13
+ // ../shared/src/async.ts
14
+ var TIMEOUT = /* @__PURE__ */ Symbol("timeout");
15
+ async function raceWithTimeout(promise, ms) {
16
+ let timer;
17
+ try {
18
+ return await Promise.race([
19
+ promise,
20
+ new Promise((resolve) => {
21
+ timer = setTimeout(() => resolve(TIMEOUT), ms);
22
+ })
23
+ ]);
24
+ } finally {
25
+ clearTimeout(timer);
26
+ promise.catch(() => {
27
+ });
28
+ }
29
+ }
30
+ async function withTimeout(promise, ms, message2) {
31
+ const result = await raceWithTimeout(promise, ms);
32
+ if (result === TIMEOUT) {
33
+ throw new Error(message2);
34
+ }
35
+ return result;
36
+ }
37
+
13
38
  // ../shared/src/result.ts
14
39
  function createSuccessResult(data) {
15
40
  return { ok: true, data };
@@ -78,6 +103,14 @@ function getProviderDisplayName(provider2, variant = "short") {
78
103
  }
79
104
  }
80
105
 
106
+ // ../shared/src/api-casing.ts
107
+ var toCamel = (key) => key.replace(/_([a-z0-9])/g, (_, char) => char.toUpperCase());
108
+ function withCamelCaseKeys(body) {
109
+ if (!isRecord(body)) return body;
110
+ const aliases = Object.entries(body).filter(([key]) => key.includes("_") && !(toCamel(key) in body));
111
+ return aliases.length ? { ...body, ...Object.fromEntries(aliases.map(([key, entry]) => [toCamel(key), entry])) } : body;
112
+ }
113
+
81
114
  // ../shared/src/aster.ts
82
115
  var ASTER_PROVIDER = "aster";
83
116
  var ASTER_BASE_URL = "https://api.asterlab.ai/v1";
@@ -1246,6 +1279,7 @@ var sendChatMessageRequestSchema = z3.object({
1246
1279
  thinkingLevel: z3.enum(VALID_THINKING_LEVELS).optional(),
1247
1280
  goalMode: z3.boolean().optional(),
1248
1281
  fastMode: z3.boolean().optional(),
1282
+ ultrafastMode: z3.boolean().optional(),
1249
1283
  source: z3.enum(MESSAGE_SOURCES).optional(),
1250
1284
  enableInteractiveTools: z3.boolean().optional(),
1251
1285
  type: z3.string().min(1).optional(),
@@ -1462,7 +1496,8 @@ function parseChatHistoryCursor(value) {
1462
1496
  function createChatHistoryCursor(cursor, mode = "range") {
1463
1497
  return cursor.events === null && cursor.turns === null ? null : JSON.stringify({ mode, ...cursor });
1464
1498
  }
1465
- function chatHistoryPageParamsFromQuery(query) {
1499
+ function chatHistoryPageParamsFromQuery(rawQuery) {
1500
+ const query = withCamelCaseKeys(rawQuery);
1466
1501
  const parse = (value) => {
1467
1502
  if (value === void 0) return void 0;
1468
1503
  const parsed = Number.parseInt(value, 10);
@@ -1472,7 +1507,8 @@ function chatHistoryPageParamsFromQuery(query) {
1472
1507
  limit: parse(query.limit),
1473
1508
  beforeEvent: parse(query.beforeEvent),
1474
1509
  beforeTurn: parse(query.beforeTurn),
1475
- beforeCursor: query.beforeCursor || void 0
1510
+ beforeCursor: query.beforeCursor || void 0,
1511
+ afterCursor: query.afterCursor || void 0
1476
1512
  };
1477
1513
  }
1478
1514
  function getChatHistoryPageWindow(totalItems, limit, before) {
@@ -1832,31 +1868,6 @@ function safeJsonParse(str, fallback) {
1832
1868
  }
1833
1869
  }
1834
1870
 
1835
- // ../shared/src/async.ts
1836
- var TIMEOUT = /* @__PURE__ */ Symbol("timeout");
1837
- async function raceWithTimeout(promise, ms) {
1838
- let timer;
1839
- try {
1840
- return await Promise.race([
1841
- promise,
1842
- new Promise((resolve) => {
1843
- timer = setTimeout(() => resolve(TIMEOUT), ms);
1844
- })
1845
- ]);
1846
- } finally {
1847
- clearTimeout(timer);
1848
- promise.catch(() => {
1849
- });
1850
- }
1851
- }
1852
- async function withTimeout(promise, ms, message2) {
1853
- const result = await raceWithTimeout(promise, ms);
1854
- if (result === TIMEOUT) {
1855
- throw new Error(message2);
1856
- }
1857
- return result;
1858
- }
1859
-
1860
1871
  // ../shared/src/agent-quota.ts
1861
1872
  var OUT_OF_CREDITS_PATTERNS = [
1862
1873
  /credit balance is too low/,
@@ -3946,7 +3957,7 @@ Create tickets, fetch issues, update state, add comments, and search through \`r
3946
3957
 
3947
3958
  Use this when:
3948
3959
  - You need to create a Linear ticket or issue
3949
- - You encounter a Linear issue link and need to understand the task
3960
+ - You encounter a linear.app issue link and need to understand the task
3950
3961
  - You need to update an issue's state or add a comment
3951
3962
  - You need to search Linear issues
3952
3963
  - A Linear request failed with an authentication error`;
@@ -4004,6 +4015,8 @@ const issue = await replicas.linear.graphql({
4004
4015
  });
4005
4016
  \`\`\`
4006
4017
 
4018
+ For a link such as \`https://linear.app/acme/issue/ENG-123/fix-login\`, the identifier is the path segment after \`/issue/\` (\`ENG-123\`).
4019
+
4007
4020
  ## Update and comment in one script
4008
4021
 
4009
4022
  \`\`\`ts
@@ -4040,7 +4053,7 @@ For screenshots, recordings, diagrams, or other media, read \`references/MEDIA.m
4040
4053
  var LINEAR_ABILITY = {
4041
4054
  label: "Linear",
4042
4055
  description: "Create tickets, fetch issues, comment, and update state through @replicas/sdk.",
4043
- bullet: "- Interacting with Linear (creating tickets, fetching issues, updating state, commenting, or troubleshooting authentication): use replicas.linear.graphql from @replicas/sdk, which refreshes tokens automatically and needs no Linear MCP server. Read references/LINEAR.md before treating a rejected workspace token as a disconnected integration.",
4056
+ bullet: "- Interacting with Linear (creating tickets, fetching issues including any linear.app link the user shares, updating state, commenting, or troubleshooting authentication): use replicas.linear.graphql from @replicas/sdk, which refreshes tokens automatically and needs no Linear MCP server. Read references/LINEAR.md before treating a rejected workspace token as a disconnected integration.",
4044
4057
  section: SECTION6,
4045
4058
  referenceFile: { name: "LINEAR.md", content: REFERENCE6 }
4046
4059
  };
@@ -4964,6 +4977,7 @@ Read issues and project data through the workspace-scoped TypeScript SDK.
4964
4977
  **Reference:** \`references/SENTRY.md\`
4965
4978
 
4966
4979
  Use this when:
4980
+ - A user shares a sentry.io link
4967
4981
  - You need to inspect Sentry projects or issues
4968
4982
  - A user asks for error-monitoring context outside a webhook-triggered task`;
4969
4983
  var REFERENCE11 = `# Sentry Integration
@@ -4978,12 +4992,23 @@ import { replicas } from '@replicas/sdk';
4978
4992
  const issues = await replicas.sentry.request('/organizations/acme/issues/?query=is:unresolved');
4979
4993
  \`\`\`
4980
4994
 
4995
+ ## Read a pasted issue link
4996
+
4997
+ Map the link to API paths instead of fetching the page. For \`https://acme.sentry.io/issues/4512345678/?project=123\` or \`https://sentry.io/organizations/acme/issues/4512345678/\`, the organization slug is \`acme\` and the issue ID is \`4512345678\`:
4998
+
4999
+ \`\`\`ts
5000
+ const issue = await replicas.sentry.request('/organizations/acme/issues/4512345678/');
5001
+ const latest = await replicas.sentry.request('/organizations/acme/issues/4512345678/events/latest/');
5002
+ \`\`\`
5003
+
5004
+ A link ending in \`/events/<eventId>/\` names a specific event: \`/organizations/acme/issues/4512345678/events/<eventId>/\`. Resolve a short ID such as \`BACKEND-1A2\` with \`/organizations/acme/shortids/BACKEND-1A2/\`. The event's \`entries\` hold the stack trace and breadcrumbs.
5005
+
4981
5006
  Pass only a relative Sentry API path. The Replicas gateway selects the connected organization credential and rejects writes, absolute URLs, oversized responses, and long-running requests.
4982
5007
  `;
4983
5008
  var SENTRY_ABILITY = {
4984
5009
  label: "Sentry",
4985
5010
  description: "Read Sentry projects and issues through @replicas/sdk.",
4986
- bullet: "- Interacting with Sentry (reading projects, issues, and error context)",
5011
+ bullet: "- Interacting with Sentry (reading projects, issues, and error context, including any sentry.io link the user shares): use replicas.sentry.request from @replicas/sdk. Read references/SENTRY.md to turn an issue link into API paths.",
4987
5012
  section: SECTION11,
4988
5013
  referenceFile: { name: "SENTRY.md", content: REFERENCE11 }
4989
5014
  };
@@ -5234,8 +5259,8 @@ var automationUpdateToolInputSchema = automationToolInputSchema.partial().extend
5234
5259
  var chatPath = { id: z15.string().describe("Workspace ID"), chat_id: z15.string().describe("Chat ID") };
5235
5260
  var { provider, model, thinkingLevel, title, message } = forkChatRequestSchema.shape;
5236
5261
  var createChatToolInputSchema = z15.object({ id: chatPath.id, provider, title: createChatRequestSchema.shape.title });
5237
- var forkChatToolInputSchema = z15.object({ ...chatPath, provider, model, thinkingLevel, title, message });
5238
- var renameChatToolInputSchema = z15.object({ ...chatPath, ...updateChatDisplayNameRequestSchema.shape });
5262
+ var forkChatToolInputSchema = z15.object({ ...chatPath, provider, model, thinking_level: thinkingLevel, title, message });
5263
+ var renameChatToolInputSchema = z15.object({ ...chatPath, display_name: updateChatDisplayNameRequestSchema.shape.displayName });
5239
5264
  var runCommandToolInputSchema = z15.object({ id: chatPath.id, ...workspaceExecRequestSchema.shape });
5240
5265
  var environmentMcpPath = { environment_id: z15.string().describe("Environment ID") };
5241
5266
  var createEnvironmentMcpToolInputSchema = z15.object({ ...environmentMcpPath, ...createEnvironmentMcpRequestSchema.shape });
@@ -9476,36 +9501,46 @@ async function readJsonlPage(args) {
9476
9501
  throw new RangeError("Invalid JSONL page");
9477
9502
  }
9478
9503
  let startByte = endByte;
9479
- let bytes = new Uint8Array();
9480
- let items = [];
9481
- while (startByte > 0 && items.length < args.limit && (endByte - startByte < MAX_SOURCE_PAGE_BYTES || !bytes.subarray(0, -1).includes(10))) {
9482
- const nextStartByte = Math.max(0, startByte - SOURCE_RANGE_BYTES);
9504
+ let head = new Uint8Array();
9505
+ let headTerminated = false;
9506
+ let lineBreaks = 0;
9507
+ let endsWithLineBreak = false;
9508
+ const pages = [];
9509
+ let itemCount = 0;
9510
+ while (startByte > 0 && itemCount < args.limit && (endByte - startByte < MAX_SOURCE_PAGE_BYTES || lineBreaks - (endsWithLineBreak ? 1 : 0) === 0)) {
9511
+ const read = endByte - startByte;
9512
+ const nextStartByte = Math.max(0, startByte - (read < MAX_SOURCE_PAGE_BYTES ? Math.min(Math.max(SOURCE_RANGE_BYTES, read), MAX_SOURCE_PAGE_BYTES - read) : SOURCE_RANGE_BYTES));
9483
9513
  const chunk = await readExactRange(
9484
9514
  args.readRange,
9485
9515
  nextStartByte,
9486
9516
  startByte,
9487
9517
  "Incomplete JSONL page read"
9488
9518
  );
9489
- const combined = new Uint8Array(chunk.length + bytes.length);
9490
- combined.set(chunk);
9491
- combined.set(bytes, chunk.length);
9492
- bytes = combined;
9519
+ if (startByte === endByte) endsWithLineBreak = chunk[chunk.length - 1] === 10;
9520
+ for (let index = chunk.indexOf(10); index !== -1; index = chunk.indexOf(10, index + 1)) lineBreaks++;
9521
+ const bytes = new Uint8Array(chunk.length + head.length + (headTerminated ? 1 : 0));
9522
+ bytes.set(chunk);
9523
+ bytes.set(head, chunk.length);
9524
+ if (headTerminated) bytes[bytes.length - 1] = 10;
9493
9525
  startByte = nextStartByte;
9494
- items = [];
9495
- let lineStart = 0;
9496
- for (let lineEnd = bytes.indexOf(10); lineEnd !== -1; lineEnd = bytes.indexOf(10, lineStart)) {
9497
- if (!(startByte > 0 && lineStart === 0)) {
9498
- try {
9499
- const item = args.parse(JSON.parse(decoder.decode(bytes.subarray(lineStart, lineEnd))));
9500
- if (item !== void 0) items.push({ item, startByte: startByte + lineStart });
9501
- } catch {
9502
- }
9526
+ const firstLineEnd = bytes.indexOf(10);
9527
+ const page = [];
9528
+ let lineStart = startByte > 0 ? firstLineEnd + 1 : 0;
9529
+ for (let lineEnd = bytes.indexOf(10, lineStart); lineEnd !== -1; lineEnd = bytes.indexOf(10, lineStart)) {
9530
+ try {
9531
+ const item = args.parse(JSON.parse(decoder.decode(bytes.subarray(lineStart, lineEnd))));
9532
+ if (item !== void 0) page.push({ item, startByte: startByte + lineStart });
9533
+ } catch {
9503
9534
  }
9504
9535
  lineStart = lineEnd + 1;
9505
9536
  }
9537
+ head = firstLineEnd === -1 ? bytes : bytes.subarray(0, startByte > 0 ? firstLineEnd : 0);
9538
+ headTerminated = firstLineEnd !== -1;
9539
+ pages.push(page);
9540
+ itemCount += page.length;
9506
9541
  }
9507
- const selected = items.slice(-args.limit);
9508
- const firstCompleteLine = bytes.indexOf(10) + 1;
9542
+ const selected = pages.reverse().flat().slice(-args.limit);
9543
+ const firstCompleteLine = headTerminated ? head.length + 1 : 0;
9509
9544
  let before = 0;
9510
9545
  if (selected.length === args.limit) before = selected[0].startByte;
9511
9546
  else if (startByte > 0) {
@@ -9517,6 +9552,26 @@ async function readJsonlPage(args) {
9517
9552
  before: before > 0 ? String(before) : null
9518
9553
  };
9519
9554
  }
9555
+ var MAX_APPENDED_BYTES = 4 * 1024 * 1024;
9556
+ async function readJsonlAppended(args) {
9557
+ const start = /^(0|[1-9]\d*)$/.test(args.after) ? Number(args.after) : Number.NaN;
9558
+ if (!Number.isSafeInteger(start) || start > args.size || args.size - start > MAX_APPENDED_BYTES) return null;
9559
+ if (start === args.size) return { items: [], after: args.after };
9560
+ const from = Math.max(0, start - 1);
9561
+ const bytes = await readExactRange(args.readRange, from, args.size, "Incomplete JSONL append read");
9562
+ if (start > 0 && bytes[0] !== 10) return null;
9563
+ const items = [];
9564
+ let lineStart = start - from;
9565
+ for (let lineEnd = bytes.indexOf(10, lineStart); lineEnd !== -1; lineEnd = bytes.indexOf(10, lineStart)) {
9566
+ try {
9567
+ const item = args.parse(JSON.parse(decoder.decode(bytes.subarray(lineStart, lineEnd))));
9568
+ if (item !== void 0) items.push(item);
9569
+ } catch {
9570
+ }
9571
+ lineStart = lineEnd + 1;
9572
+ }
9573
+ return { items, after: String(from + lineStart) };
9574
+ }
9520
9575
  function parseChatTranscriptHistoryIndex(value) {
9521
9576
  if (!isRecord(value) || value.version !== 2 || !isNonNegativeInteger(value.sourceSize)) return void 0;
9522
9577
  const removedMessageIds = Array.isArray(value.removedMessageIds) ? value.removedMessageIds.filter((id) => typeof id === "string") : [];
@@ -9884,6 +9939,7 @@ export {
9884
9939
  searchRepoFileIndex,
9885
9940
  isExcludedRepoFilePath,
9886
9941
  readJsonlPage,
9942
+ readJsonlAppended,
9887
9943
  normalizeChatTranscriptMetadata,
9888
9944
  parseChatTranscriptArtifact,
9889
9945
  readSseStream,
@@ -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-SXWQC3OB.js";
7
- import "./chunk-WRAVQEOB.js";
8
- import "./chunk-SEYXPQY7.js";
6
+ } from "./chunk-ITBCLNN5.js";
7
+ import "./chunk-BPPOGNJ5.js";
8
+ import "./chunk-2OZUYL37.js";
9
9
  import {
10
10
  isRecord
11
11
  } from "./chunk-UZSNFLDQ.js";
12
- import "./chunk-MD2DJUY2.js";
12
+ import "./chunk-KKQJOAN5.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/command-protection-hook.ts
@@ -7,12 +7,12 @@ import {
7
7
  import {
8
8
  AppServerProcess,
9
9
  buildCodexAgentEnv
10
- } from "./chunk-F52XMCMW.js";
11
- import "./chunk-SEYXPQY7.js";
10
+ } from "./chunk-ILNLBD7M.js";
11
+ import "./chunk-2OZUYL37.js";
12
12
  import {
13
13
  AGENT,
14
14
  headlessAgentRequestSchema
15
- } from "./chunk-MD2DJUY2.js";
15
+ } from "./chunk-KKQJOAN5.js";
16
16
  import "./chunk-VEQXQN22.js";
17
17
 
18
18
  // src/headless-agent.ts