@rallycry/conveyor-agent 10.11.0 → 10.12.0

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.
@@ -2444,7 +2444,17 @@ var PtyChatEventPayloadSchema = z2.discriminatedUnion("kind", [
2444
2444
  kind: z2.literal("tool_use"),
2445
2445
  name: z2.string().max(200),
2446
2446
  // Compact preview: JSON.stringify(input) truncated agent-side.
2447
- input: z2.string().max(2e3)
2447
+ input: z2.string().max(2e3),
2448
+ // Transcript tool_use block id — lets the client pair the tool_result.
2449
+ id: z2.string().max(100).optional()
2450
+ }),
2451
+ z2.object({
2452
+ kind: z2.literal("tool_result"),
2453
+ // tool_use block id this result answers (absent on malformed records).
2454
+ toolUseId: z2.string().max(100).optional(),
2455
+ // Compact output preview, truncated agent-side.
2456
+ output: z2.string().max(2e3),
2457
+ isError: z2.boolean().optional()
2448
2458
  }),
2449
2459
  z2.object({ kind: z2.literal("turn_end") })
2450
2460
  ]);
@@ -2823,7 +2833,9 @@ var UpdateProjectTagRequestSchema = z4.object({
2823
2833
  var PostToProjectChatRequestSchema = z4.object({
2824
2834
  projectId: z4.string(),
2825
2835
  content: z4.string().min(1).max(2e4),
2826
- requestingUserId: z4.string().optional()
2836
+ requestingUserId: z4.string().optional(),
2837
+ /** Marks the post so the server can persist it beyond chat (tag-audit summaries land in tag history). */
2838
+ kind: z4.enum(["tag_audit_summary"]).optional()
2827
2839
  });
2828
2840
  var StartTagAuditRequestSchema = z4.object({
2829
2841
  projectId: z4.string(),
@@ -2834,6 +2846,9 @@ var StartTaskAuditRequestSchema = z4.object({
2834
2846
  taskIds: z4.array(z4.string()).min(1).max(20),
2835
2847
  requestingUserId: z4.string().optional()
2836
2848
  });
2849
+ var GetActiveAuditSessionsRequestSchema = z4.object({
2850
+ projectId: z4.string()
2851
+ });
2837
2852
  var ReportTaskAuditResultRequestSchema = z4.object({
2838
2853
  projectId: z4.string(),
2839
2854
  taskId: z4.string(),
@@ -3629,6 +3644,7 @@ function matchUsageLimitBanner(text, now = Date.now()) {
3629
3644
  // src/harness/pty/chat-record-mapper.ts
3630
3645
  var TEXT_MAX = 16e3;
3631
3646
  var TOOL_INPUT_MAX = 1900;
3647
+ var TOOL_OUTPUT_MAX = 1900;
3632
3648
  function isRecord2(value) {
3633
3649
  return typeof value === "object" && value !== null;
3634
3650
  }
@@ -3678,16 +3694,42 @@ function mapAssistant2(record) {
3678
3694
  const name = stringField2(raw, "name");
3679
3695
  if (name) {
3680
3696
  const input = "input" in raw ? raw.input : void 0;
3681
- events.push({
3697
+ const event = {
3682
3698
  kind: "tool_use",
3683
3699
  name: truncate(name, 200),
3684
3700
  input: JSON.stringify(input ?? {}).slice(0, TOOL_INPUT_MAX)
3685
- });
3701
+ };
3702
+ const id = stringField2(raw, "id");
3703
+ if (id !== void 0) event.id = id;
3704
+ events.push(event);
3686
3705
  }
3687
3706
  }
3688
3707
  }
3689
3708
  return events;
3690
3709
  }
3710
+ function toolResultText(block) {
3711
+ const content = block.content;
3712
+ if (typeof content === "string") return content;
3713
+ if (isUnknownArray2(content)) {
3714
+ return content.filter((b) => isRecord2(b) && b.type === "text").map((b) => typeof b.text === "string" ? b.text : "").filter((t) => t.length > 0).join("\n");
3715
+ }
3716
+ return "";
3717
+ }
3718
+ function mapToolResults(content) {
3719
+ const events = [];
3720
+ for (const raw of content) {
3721
+ if (!isRecord2(raw) || raw.type !== "tool_result") continue;
3722
+ const event = {
3723
+ kind: "tool_result",
3724
+ output: truncate(toolResultText(raw), TOOL_OUTPUT_MAX),
3725
+ isError: raw.is_error === true
3726
+ };
3727
+ const toolUseId = stringField2(raw, "tool_use_id");
3728
+ if (toolUseId !== void 0) event.toolUseId = toolUseId;
3729
+ events.push(event);
3730
+ }
3731
+ return events;
3732
+ }
3691
3733
  function mapUser(record) {
3692
3734
  const message = record.message;
3693
3735
  if (!isRecord2(message)) return [];
@@ -3697,7 +3739,7 @@ function mapUser(record) {
3697
3739
  text = content;
3698
3740
  } else if (isUnknownArray2(content)) {
3699
3741
  const hasToolResult = content.some((b) => isRecord2(b) && b.type === "tool_result");
3700
- if (hasToolResult) return [];
3742
+ if (hasToolResult) return mapToolResults(content);
3701
3743
  text = content.filter((b) => isRecord2(b) && b.type === "text").map((b) => typeof b.text === "string" ? b.text : "").filter((t) => t.length > 0).join("\n");
3702
3744
  } else {
3703
3745
  return [];
@@ -5417,9 +5459,52 @@ var PtySession = class {
5417
5459
  }
5418
5460
  };
5419
5461
 
5462
+ // src/harness/pty/config-home-health.ts
5463
+ import { mkdir as mkdir4 } from "fs/promises";
5464
+ import { homedir as homedir3 } from "os";
5465
+ import { join as join5 } from "path";
5466
+ var MOUNT_DISCONNECT_CODES = /* @__PURE__ */ new Set(["ENOTCONN", "EIO", "ESTALE", "ENXIO"]);
5467
+ var MOUNT_DISCONNECT_MESSAGES = [
5468
+ "socket is not connected",
5469
+ "transport endpoint is not connected"
5470
+ ];
5471
+ function isMountDisconnectError(err) {
5472
+ if (typeof err !== "object" || err === null) return false;
5473
+ const code = err.code;
5474
+ if (typeof code === "string" && MOUNT_DISCONNECT_CODES.has(code)) return true;
5475
+ const message = err.message;
5476
+ if (typeof message !== "string") return false;
5477
+ const lower = message.toLowerCase();
5478
+ return MOUNT_DISCONNECT_MESSAGES.some((needle) => lower.includes(needle));
5479
+ }
5480
+ function podLocalConfigHome() {
5481
+ return join5(homedir3(), ".claude-local");
5482
+ }
5483
+ async function ensureUsableClaudeConfigHome(cwd, log) {
5484
+ const configHome = claudeConfigHome();
5485
+ try {
5486
+ await mkdir4(join5(configHome, "projects", projectSlug(cwd)), { recursive: true });
5487
+ return { configHome, fellBack: false };
5488
+ } catch (err) {
5489
+ if (!isMountDisconnectError(err)) throw err;
5490
+ const fallback = podLocalConfigHome();
5491
+ log?.warn(
5492
+ "shared ~/.claude mount is unreachable; falling back to a pod-local config home. Session history will not persist across pods until the mount recovers.",
5493
+ {
5494
+ code: err.code ?? null,
5495
+ from: configHome,
5496
+ to: fallback
5497
+ }
5498
+ );
5499
+ process.env.CLAUDE_CONFIG_DIR = fallback;
5500
+ await mkdir4(join5(fallback, "projects", projectSlug(cwd)), { recursive: true });
5501
+ return { configHome: fallback, fellBack: true };
5502
+ }
5503
+ }
5504
+
5420
5505
  // src/harness/pty/index.ts
5421
5506
  var ENDED_GRACE_MS = 4e3;
5422
- var PtyHarness = class {
5507
+ var PtyHarness = class _PtyHarness {
5423
5508
  /**
5424
5509
  * `bridge` relays raw terminal I/O to/from the S2 server (and on to the S5
5425
5510
  * terminal). It is undefined for SDK-only callers and PTY runs that never
@@ -5431,6 +5516,7 @@ var PtyHarness = class {
5431
5516
  }
5432
5517
  bridge;
5433
5518
  adapter;
5519
+ static log = createServiceLogger("pty-harness");
5434
5520
  /** Fingerprint of the spawn-time options a reused process cannot change. */
5435
5521
  fingerprintOf(options) {
5436
5522
  return this.adapter.spawnFingerprint({
@@ -5473,6 +5559,9 @@ var PtyHarness = class {
5473
5559
  await stale.teardown();
5474
5560
  }
5475
5561
  session = new PtySession(opts.prompt, opts.options, want, this.bridge, this.adapter);
5562
+ if (this.adapter.capabilities.structuredEvents) {
5563
+ await ensureUsableClaudeConfigHome(opts.options.cwd, _PtyHarness.log);
5564
+ }
5476
5565
  await this.adapter.prepareEnvironment({ cwd: opts.options.cwd });
5477
5566
  session.onExit(() => this.handleSessionExit(session));
5478
5567
  await session.start();
@@ -7577,7 +7666,7 @@ function buildMutationTools(connection, config) {
7577
7666
 
7578
7667
  // src/tools/attachment-tools.ts
7579
7668
  import { readFile as readFile3, stat as stat4 } from "fs/promises";
7580
- import { basename, extname, isAbsolute, join as join5 } from "path";
7669
+ import { basename, extname, isAbsolute, join as join6 } from "path";
7581
7670
  import { z as z9 } from "zod";
7582
7671
  var IMAGE_MIME_BY_EXT = {
7583
7672
  ".png": "image/png",
@@ -7596,7 +7685,7 @@ function buildUploadAttachmentTool(connection, config) {
7596
7685
  },
7597
7686
  async ({ path: path4, title }) => {
7598
7687
  try {
7599
- const filePath = isAbsolute(path4) ? path4 : join5(config.workspaceDir, path4);
7688
+ const filePath = isAbsolute(path4) ? path4 : join6(config.workspaceDir, path4);
7600
7689
  const mimeType = IMAGE_MIME_BY_EXT[extname(filePath).toLowerCase()];
7601
7690
  if (!mimeType) {
7602
7691
  return textResult(
@@ -8309,7 +8398,7 @@ function createConveyorMcpServer(harness, connection, config, context, agentMode
8309
8398
 
8310
8399
  // src/harness/pty/adapters/types.ts
8311
8400
  import { accessSync, constants, statSync } from "fs";
8312
- import { join as join6 } from "path";
8401
+ import { join as join7 } from "path";
8313
8402
  var TuiUnavailableError = class extends Error {
8314
8403
  constructor(tui, message) {
8315
8404
  super(message);
@@ -8333,7 +8422,7 @@ function findOnPath(binary, env = process.env) {
8333
8422
  }
8334
8423
  for (const dir of (env.PATH ?? "").split(":")) {
8335
8424
  if (!dir) continue;
8336
- const candidate = join6(dir, binary);
8425
+ const candidate = join7(dir, binary);
8337
8426
  if (isExecutable(candidate)) return candidate;
8338
8427
  }
8339
8428
  return null;
@@ -10019,7 +10108,7 @@ var QueryBridge = class {
10019
10108
 
10020
10109
  // src/runner/session-runner-helpers.ts
10021
10110
  import { readFileSync as readFileSync2 } from "fs";
10022
- import { dirname as dirname2, join as join7 } from "path";
10111
+ import { dirname as dirname2, join as join8 } from "path";
10023
10112
  import { fileURLToPath as fileURLToPath2 } from "url";
10024
10113
  function mapChatHistory(messages) {
10025
10114
  if (!messages) return [];
@@ -10048,7 +10137,7 @@ function readAgentVersion() {
10048
10137
  const here = dirname2(fileURLToPath2(import.meta.url));
10049
10138
  for (const rel of ["../package.json", "../../package.json"]) {
10050
10139
  try {
10051
- const pkg = JSON.parse(readFileSync2(join7(here, rel), "utf-8"));
10140
+ const pkg = JSON.parse(readFileSync2(join8(here, rel), "utf-8"));
10052
10141
  if (pkg.version) return pkg.version;
10053
10142
  } catch {
10054
10143
  }
@@ -11521,12 +11610,12 @@ var SessionRunner = class _SessionRunner {
11521
11610
 
11522
11611
  // src/setup/config.ts
11523
11612
  import { readFile as readFile5 } from "fs/promises";
11524
- import { join as join8 } from "path";
11613
+ import { join as join9 } from "path";
11525
11614
  var DEVCONTAINER_PATH = ".devcontainer/conveyor/devcontainer.json";
11526
11615
  var DEVCONTAINER_PORT_DENY_LIST = /* @__PURE__ */ new Set([5432, 6379, 9200]);
11527
11616
  async function loadForwardPorts(workspaceDir) {
11528
11617
  try {
11529
- const raw = await readFile5(join8(workspaceDir, DEVCONTAINER_PATH), "utf-8");
11618
+ const raw = await readFile5(join9(workspaceDir, DEVCONTAINER_PATH), "utf-8");
11530
11619
  const parsed = JSON.parse(raw);
11531
11620
  const ports = (parsed.forwardPorts ?? []).filter(
11532
11621
  (p) => typeof p === "number" && !DEVCONTAINER_PORT_DENY_LIST.has(p)
@@ -11708,8 +11797,8 @@ export {
11708
11797
  inheritedEnv,
11709
11798
  buildPromptBytes,
11710
11799
  ClaudeTuiAdapter,
11711
- PtyHarness,
11712
11800
  createServiceLogger,
11801
+ PtyHarness,
11713
11802
  textResult,
11714
11803
  GIT_TIMEOUT_MS,
11715
11804
  hasUncommittedChanges,
@@ -11742,4 +11831,4 @@ export {
11742
11831
  runStartCommand,
11743
11832
  unshallowRepo
11744
11833
  };
11745
- //# sourceMappingURL=chunk-KEKGEDN2.js.map
11834
+ //# sourceMappingURL=chunk-CXNWRIS7.js.map