@vm0/cli 9.209.3 → 9.210.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.
@@ -60737,13 +60737,13 @@ function attributeValueToTypedAttributeValue(rawValue, useFallback) {
60737
60737
  if (!useFallback || useFallback === "skip-undefined" && value === void 0) {
60738
60738
  return;
60739
60739
  }
60740
- let stringValue = "";
60740
+ let stringValue2 = "";
60741
60741
  try {
60742
- stringValue = JSON.stringify(value) ?? "";
60742
+ stringValue2 = JSON.stringify(value) ?? "";
60743
60743
  } catch {
60744
60744
  }
60745
60745
  return {
60746
- value: stringValue,
60746
+ value: stringValue2,
60747
60747
  type: "string",
60748
60748
  ...checkedUnit
60749
60749
  };
@@ -80408,7 +80408,7 @@ if (DSN) {
80408
80408
  init2({
80409
80409
  dsn: DSN,
80410
80410
  environment: process.env.SENTRY_ENVIRONMENT ?? "production",
80411
- release: "9.209.3",
80411
+ release: "9.210.0",
80412
80412
  sendDefaultPii: false,
80413
80413
  tracesSampleRate: 0,
80414
80414
  shutdownTimeout: 500,
@@ -80427,7 +80427,7 @@ if (DSN) {
80427
80427
  }
80428
80428
  });
80429
80429
  setContext("cli", {
80430
- version: "9.209.3",
80430
+ version: "9.210.0",
80431
80431
  command: process.argv.slice(2).join(" ")
80432
80432
  });
80433
80433
  setContext("runtime", {
@@ -86687,7 +86687,7 @@ function validateBaseUrlScheme(scheme, base, serviceName2) {
86687
86687
  throw new Error(errMsg(base, serviceName2, "scheme must be http or https"));
86688
86688
  }
86689
86689
  }
86690
- function validateUrlSchemeDelimiter(value, serviceName2, label, displayValue = value) {
86690
+ function validateUrlSchemeDelimiter(value, serviceName2, label, displayValue2 = value) {
86691
86691
  if (value.includes("://")) return;
86692
86692
  const colonIndex = value.indexOf(":");
86693
86693
  if (colonIndex !== -1) {
@@ -86696,15 +86696,15 @@ function validateUrlSchemeDelimiter(value, serviceName2, label, displayValue = v
86696
86696
  const allowedScheme = label === "auth.base URL" ? scheme.toLowerCase() === REQUIRED_AUTH_BASE_URL_SCHEME : ALLOWED_BASE_URL_SCHEMES.has(scheme.toLowerCase());
86697
86697
  if (!allowedScheme) {
86698
86698
  throw new Error(
86699
- `Invalid ${label} "${displayValue}" in firewall "${serviceName2}": ${schemeDetail}`
86699
+ `Invalid ${label} "${displayValue2}" in firewall "${serviceName2}": ${schemeDetail}`
86700
86700
  );
86701
86701
  }
86702
86702
  throw new Error(
86703
- `Invalid ${label} "${displayValue}" in firewall "${serviceName2}": URL must include "://" after the scheme`
86703
+ `Invalid ${label} "${displayValue2}" in firewall "${serviceName2}": URL must include "://" after the scheme`
86704
86704
  );
86705
86705
  }
86706
86706
  throw new Error(
86707
- `Invalid ${label} "${displayValue}" in firewall "${serviceName2}": URL must include a scheme (e.g. "https://${displayValue}")`
86707
+ `Invalid ${label} "${displayValue2}" in firewall "${serviceName2}": URL must include a scheme (e.g. "https://${displayValue2}")`
86708
86708
  );
86709
86709
  }
86710
86710
  function isAscii(value) {
@@ -89082,7 +89082,14 @@ var orgMessageResponseSchema = external_exports.object({
89082
89082
 
89083
89083
  // ../../packages/api-contracts/src/contracts/orgs.ts
89084
89084
  var c5 = initContract();
89085
- var orgTierSchema = external_exports.enum(["free", "pro-suspend", "pro", "team"]);
89085
+ var orgTierSchema = external_exports.enum([
89086
+ "free",
89087
+ "limited-free-1",
89088
+ "pro-suspend",
89089
+ "pro",
89090
+ "team"
89091
+ ]);
89092
+ var ORG_TIER_SET = new Set(orgTierSchema.options);
89086
89093
  var orgSlugSchema = external_exports.string().min(3, "Org slug must be at least 3 characters").max(64, "Org slug must be at most 64 characters").regex(
89087
89094
  /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$/,
89088
89095
  "Org slug must contain only lowercase letters, numbers, and hyphens, and must start and end with an alphanumeric character"
@@ -90306,6 +90313,7 @@ var zeroModelPoliciesMainContract = c13.router({
90306
90313
  200: orgModelPoliciesResponseSchema,
90307
90314
  400: apiErrorSchema,
90308
90315
  401: apiErrorSchema,
90316
+ 402: apiErrorSchema,
90309
90317
  403: apiErrorSchema,
90310
90318
  404: apiErrorSchema,
90311
90319
  500: apiErrorSchema
@@ -90530,7 +90538,7 @@ var paginationSchema = external_exports.object({
90530
90538
  });
90531
90539
  var listQuerySchema = external_exports.object({
90532
90540
  cursor: external_exports.string().optional(),
90533
- limit: external_exports.coerce.number().min(1).max(100).default(20)
90541
+ limit: external_exports.coerce.number().int().min(1).max(100).default(20)
90534
90542
  });
90535
90543
  var c15 = initContract();
90536
90544
  var logStatusSchema = external_exports.enum([
@@ -90971,6 +90979,12 @@ var sequenceQueryNumberSchema = safeIntegerQueryNumberSchema.refine(
90971
90979
  },
90972
90980
  { message: "Sequence cursor is out of range" }
90973
90981
  );
90982
+ function boundedIntegerQueryNumberSchema(min, max) {
90983
+ return external_exports.preprocess(
90984
+ rejectBlankQueryNumber2,
90985
+ external_exports.coerce.number().int().min(min).max(max)
90986
+ );
90987
+ }
90974
90988
  function logSinceQuerySchema(cursorKind) {
90975
90989
  return cursorKind === "time" ? timestampQueryNumberSchema : sequenceQueryNumberSchema;
90976
90990
  }
@@ -91291,6 +91305,7 @@ var runNetworkLogsContract = c16.router({
91291
91305
  var searchResultSchema = external_exports.object({
91292
91306
  runId: external_exports.string(),
91293
91307
  agentName: external_exports.string(),
91308
+ framework: external_exports.string().nullable().optional(),
91294
91309
  matchedEvent: runEventSchema,
91295
91310
  contextBefore: external_exports.array(runEventSchema),
91296
91311
  contextAfter: external_exports.array(runEventSchema)
@@ -91299,6 +91314,15 @@ var logsSearchResponseSchema = external_exports.object({
91299
91314
  results: external_exports.array(searchResultSchema),
91300
91315
  hasMore: external_exports.boolean()
91301
91316
  });
91317
+ var logsSearchQuerySchema = external_exports.object({
91318
+ keyword: external_exports.string().trim().min(1),
91319
+ agentId: external_exports.string().uuid().optional(),
91320
+ runId: external_exports.string().uuid().optional(),
91321
+ since: timestampQueryNumberSchema.optional(),
91322
+ limit: boundedIntegerQueryNumberSchema(1, 50).default(20),
91323
+ before: boundedIntegerQueryNumberSchema(0, 10).default(0),
91324
+ after: boundedIntegerQueryNumberSchema(0, 10).default(0)
91325
+ });
91302
91326
  var logsSearchContract = c16.router({
91303
91327
  /**
91304
91328
  * GET /api/logs/search
@@ -91308,15 +91332,7 @@ var logsSearchContract = c16.router({
91308
91332
  method: "GET",
91309
91333
  path: "/api/logs/search",
91310
91334
  headers: authHeadersSchema,
91311
- query: external_exports.object({
91312
- keyword: external_exports.string().min(1),
91313
- agentId: external_exports.string().uuid().optional(),
91314
- runId: external_exports.string().optional(),
91315
- since: timestampQueryNumberSchema.optional(),
91316
- limit: external_exports.coerce.number().min(1).max(50).default(20),
91317
- before: external_exports.coerce.number().min(0).max(10).default(0),
91318
- after: external_exports.coerce.number().min(0).max(10).default(0)
91319
- }),
91335
+ query: logsSearchQuerySchema,
91320
91336
  responses: {
91321
91337
  200: logsSearchResponseSchema,
91322
91338
  400: apiErrorSchema,
@@ -91946,6 +91962,7 @@ var chatThreadByIdContract = c18.router({
91946
91962
  204: c18.noBody(),
91947
91963
  400: apiErrorSchema,
91948
91964
  401: apiErrorSchema,
91965
+ 402: apiErrorSchema,
91949
91966
  404: apiErrorSchema
91950
91967
  },
91951
91968
  summary: "Delete a chat thread",
@@ -92037,6 +92054,7 @@ var chatThreadModelSelectionContract = c18.router({
92037
92054
  204: c18.noBody(),
92038
92055
  400: apiErrorSchema,
92039
92056
  401: apiErrorSchema,
92057
+ 402: apiErrorSchema,
92040
92058
  404: apiErrorSchema
92041
92059
  },
92042
92060
  summary: "Update a chat thread model selection"
@@ -92179,7 +92197,7 @@ var chatSearchContract = c18.router({
92179
92197
  path: "/api/zero/chat/search",
92180
92198
  headers: authHeadersSchema,
92181
92199
  query: external_exports.object({
92182
- keyword: external_exports.string().min(1),
92200
+ keyword: external_exports.string().trim().min(1),
92183
92201
  agentId: external_exports.string().uuid().optional(),
92184
92202
  since: external_exports.coerce.number().optional(),
92185
92203
  limit: external_exports.coerce.number().min(1).max(50).default(20),
@@ -94359,15 +94377,7 @@ var zeroLogsSearchContract = c27.router({
94359
94377
  method: "GET",
94360
94378
  path: "/api/zero/logs/search",
94361
94379
  headers: authHeadersSchema,
94362
- query: external_exports.object({
94363
- keyword: external_exports.string().min(1),
94364
- agentId: external_exports.string().uuid().optional(),
94365
- runId: external_exports.string().optional(),
94366
- since: timestampQueryNumberSchema.optional(),
94367
- limit: external_exports.coerce.number().min(1).max(50).default(20),
94368
- before: external_exports.coerce.number().min(0).max(10).default(0),
94369
- after: external_exports.coerce.number().min(0).max(10).default(0)
94370
- }),
94380
+ query: logsSearchQuerySchema,
94371
94381
  responses: {
94372
94382
  200: logsSearchResponseSchema,
94373
94383
  400: apiErrorSchema,
@@ -95842,6 +95852,9 @@ var zeroWorkflowScheduleSchema = external_exports.discriminatedUnion("type", [
95842
95852
  var unattendedTriggerPermissionActionSchema = firewallPolicyValueSchema.exclude(["ask"]);
95843
95853
  var unattendedTriggerConnectorRefSchema = external_exports.string().min(1).max(64);
95844
95854
  var unattendedTriggerPermissionKeySchema = external_exports.string().min(1).max(128);
95855
+ var unattendedTriggerConnectorRefsSchema = external_exports.array(
95856
+ unattendedTriggerConnectorRefSchema
95857
+ );
95845
95858
  var unattendedTriggerPermissionPolicySchema = external_exports.record(
95846
95859
  unattendedTriggerConnectorRefSchema,
95847
95860
  external_exports.object({
@@ -95852,6 +95865,7 @@ var unattendedTriggerPermissionPolicySchema = external_exports.record(
95852
95865
  })
95853
95866
  );
95854
95867
  var setUnattendedTriggerPermissionPolicyRequestSchema = external_exports.object({
95868
+ unattendedConnectorRefs: unattendedTriggerConnectorRefsSchema.optional(),
95855
95869
  unattendedPermissionPolicy: unattendedTriggerPermissionPolicySchema.nullable()
95856
95870
  });
95857
95871
  var zeroWorkflowTriggerSummaryBaseSchema = external_exports.object({
@@ -95861,6 +95875,7 @@ var zeroWorkflowTriggerSummaryBaseSchema = external_exports.object({
95861
95875
  chatThreadId: external_exports.string().nullable(),
95862
95876
  nextRunAt: external_exports.string().datetime().nullable(),
95863
95877
  lastRunAt: external_exports.string().datetime().nullable(),
95878
+ unattendedConnectorRefs: unattendedTriggerConnectorRefsSchema,
95864
95879
  unattendedPermissionPolicy: unattendedTriggerPermissionPolicySchema.nullable()
95865
95880
  });
95866
95881
  var zeroWorkflowScheduleTriggerSummarySchema = zeroWorkflowTriggerSummaryBaseSchema.extend({
@@ -96274,21 +96289,6 @@ var zeroWorkflowTriggersContract = c32.router({
96274
96289
  },
96275
96290
  summary: "Disable a workflow trigger"
96276
96291
  },
96277
- run: {
96278
- method: "POST",
96279
- path: "/api/zero/workflow-triggers/:id/run",
96280
- headers: authHeadersSchema,
96281
- pathParams: triggerIdParams,
96282
- body: c32.noBody(),
96283
- responses: {
96284
- 200: external_exports.object({ runId: external_exports.string() }),
96285
- 401: apiErrorSchema,
96286
- 403: apiErrorSchema,
96287
- 404: apiErrorSchema,
96288
- 409: apiErrorSchema
96289
- },
96290
- summary: "Fire a one-off test run of a workflow trigger"
96291
- },
96292
96292
  setPermissionPolicy: {
96293
96293
  method: "PUT",
96294
96294
  path: "/api/zero/workflow-triggers/:id/permission-policy",
@@ -96408,13 +96408,6 @@ async function disableWorkflowTrigger(id) {
96408
96408
  if (result.status === 200) return result.body;
96409
96409
  handleError(result, `Failed to disable workflow trigger "${id}"`);
96410
96410
  }
96411
- async function runWorkflowTrigger(id) {
96412
- const config3 = await getClientConfig();
96413
- const client = initClient(zeroWorkflowTriggersContract, config3);
96414
- const result = await client.run({ params: { id } });
96415
- if (result.status === 200) return result.body;
96416
- handleError(result, `Failed to run workflow trigger "${id}"`);
96417
- }
96418
96411
 
96419
96412
  // src/lib/api/domains/integrations-slack.ts
96420
96413
  init_esm_shims();
@@ -101569,6 +101562,45 @@ async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
101569
101562
  return isEmpty;
101570
101563
  }
101571
101564
 
101565
+ // ../../packages/core/src/frameworks.ts
101566
+ init_esm_shims();
101567
+ var SUPPORTED_FRAMEWORKS = ["claude-code", "codex"];
101568
+ function isSupportedFramework(framework) {
101569
+ if (!framework) return false;
101570
+ return SUPPORTED_FRAMEWORKS.includes(framework);
101571
+ }
101572
+ function assertSupportedFramework(framework, context2) {
101573
+ if (!isSupportedFramework(framework)) {
101574
+ const contextMsg = context2 ? ` in ${context2}` : "";
101575
+ throw new Error(
101576
+ `Unsupported framework "${framework}"${contextMsg}. Supported frameworks: ${SUPPORTED_FRAMEWORKS.join(", ")}`
101577
+ );
101578
+ }
101579
+ }
101580
+ function getValidatedFramework(framework) {
101581
+ if (framework === void 0) {
101582
+ return "claude-code";
101583
+ }
101584
+ assertSupportedFramework(framework);
101585
+ return framework;
101586
+ }
101587
+ var FRAMEWORK_DISPLAY_NAMES = {
101588
+ "claude-code": "Claude Code",
101589
+ codex: "Codex"
101590
+ };
101591
+ function getFrameworkDisplayName(framework) {
101592
+ assertSupportedFramework(framework);
101593
+ return FRAMEWORK_DISPLAY_NAMES[framework];
101594
+ }
101595
+ var FRAMEWORK_INSTRUCTIONS_FILENAMES = {
101596
+ "claude-code": "CLAUDE.md",
101597
+ codex: "AGENTS.md"
101598
+ };
101599
+ function getInstructionsFilename(framework) {
101600
+ const validated = getValidatedFramework(framework);
101601
+ return FRAMEWORK_INSTRUCTIONS_FILENAMES[validated];
101602
+ }
101603
+
101572
101604
  // ../../packages/core/src/resource-registry.ts
101573
101605
  init_esm_shims();
101574
101606
  var PRESENTATION_REQUIRED_RESOURCE_IDS = [
@@ -109811,6 +109843,26 @@ var onboardingSetupContract = c63.router({
109811
109843
  summary: "Complete admin onboarding in a single request"
109812
109844
  }
109813
109845
  });
109846
+ var onboardingCompleteLimitedFreeContract = c63.router({
109847
+ complete: {
109848
+ method: "POST",
109849
+ path: "/api/zero/onboarding/complete-limited-free",
109850
+ headers: authHeadersSchema,
109851
+ body: external_exports.object({}).strict(),
109852
+ responses: {
109853
+ 200: external_exports.object({
109854
+ agentId: external_exports.string(),
109855
+ tier: external_exports.literal("limited-free-1"),
109856
+ needsOnboarding: external_exports.literal(false)
109857
+ }),
109858
+ 400: apiErrorSchema,
109859
+ 401: apiErrorSchema,
109860
+ 403: apiErrorSchema,
109861
+ 409: apiErrorSchema
109862
+ },
109863
+ summary: "Complete onboarding and enter the limited free tier"
109864
+ }
109865
+ });
109814
109866
 
109815
109867
  // ../../packages/api-contracts/src/contracts/skills.ts
109816
109868
  init_esm_shims();
@@ -112142,45 +112194,6 @@ function getInstructionsStorageName(agentName) {
112142
112194
  // ../../packages/core/src/github-url.ts
112143
112195
  init_esm_shims();
112144
112196
 
112145
- // ../../packages/core/src/frameworks.ts
112146
- init_esm_shims();
112147
- var SUPPORTED_FRAMEWORKS = ["claude-code", "codex"];
112148
- function isSupportedFramework(framework) {
112149
- if (!framework) return false;
112150
- return SUPPORTED_FRAMEWORKS.includes(framework);
112151
- }
112152
- function assertSupportedFramework(framework, context2) {
112153
- if (!isSupportedFramework(framework)) {
112154
- const contextMsg = context2 ? ` in ${context2}` : "";
112155
- throw new Error(
112156
- `Unsupported framework "${framework}"${contextMsg}. Supported frameworks: ${SUPPORTED_FRAMEWORKS.join(", ")}`
112157
- );
112158
- }
112159
- }
112160
- function getValidatedFramework(framework) {
112161
- if (framework === void 0) {
112162
- return "claude-code";
112163
- }
112164
- assertSupportedFramework(framework);
112165
- return framework;
112166
- }
112167
- var FRAMEWORK_DISPLAY_NAMES = {
112168
- "claude-code": "Claude Code",
112169
- codex: "Codex"
112170
- };
112171
- function getFrameworkDisplayName(framework) {
112172
- assertSupportedFramework(framework);
112173
- return FRAMEWORK_DISPLAY_NAMES[framework];
112174
- }
112175
- var FRAMEWORK_INSTRUCTIONS_FILENAMES = {
112176
- "claude-code": "CLAUDE.md",
112177
- codex: "AGENTS.md"
112178
- };
112179
- function getInstructionsFilename(framework) {
112180
- const validated = getValidatedFramework(framework);
112181
- return FRAMEWORK_INSTRUCTIONS_FILENAMES[validated];
112182
- }
112183
-
112184
112197
  // ../../packages/core/src/feature-switch-key.ts
112185
112198
  init_esm_shims();
112186
112199
 
@@ -112678,207 +112691,766 @@ var ClaudeEventParser = class {
112678
112691
 
112679
112692
  // src/lib/events/codex-event-parser.ts
112680
112693
  init_esm_shims();
112694
+ var MAX_FORMATTED_ARRAY_ITEMS = 6;
112695
+ var MAX_FORMATTED_ARRAY_DEPTH = 4;
112696
+ var MAX_FORMATTED_OBJECT_FIELDS = 8;
112697
+ var MAX_FORMATTED_OBJECT_INSPECTED_FIELDS = 16;
112698
+ var MAX_FORMATTED_TEXT_LENGTH = 240;
112699
+ var MAX_ERROR_SIGNAL_DEPTH = 8;
112700
+ var MAX_FORMATTED_PLAN_STEPS = 20;
112701
+ var MAX_FORMATTED_FILE_CHANGES = 20;
112702
+ function asRecord(value) {
112703
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
112704
+ return null;
112705
+ }
112706
+ return value;
112707
+ }
112708
+ function hasOwnKey(record, key) {
112709
+ return Object.prototype.hasOwnProperty.call(record, key);
112710
+ }
112711
+ function stringValue(value) {
112712
+ return typeof value === "string" ? value : void 0;
112713
+ }
112714
+ function nonEmptyStringValue(value) {
112715
+ const valueString = stringValue(value);
112716
+ return valueString && valueString.length > 0 ? valueString : void 0;
112717
+ }
112718
+ function trimmedStringValue(value) {
112719
+ const valueString = stringValue(value)?.trim();
112720
+ return valueString && valueString.length > 0 ? valueString : void 0;
112721
+ }
112722
+ function numberValue(value) {
112723
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
112724
+ }
112725
+ function getFirstString(record, keys) {
112726
+ for (const key of keys) {
112727
+ const value = trimmedStringValue(record[key]);
112728
+ if (value) {
112729
+ return value;
112730
+ }
112731
+ }
112732
+ return void 0;
112733
+ }
112734
+ function getFirstNumber(record, keys) {
112735
+ for (const key of keys) {
112736
+ const value = numberValue(record[key]);
112737
+ if (value !== void 0) {
112738
+ return value;
112739
+ }
112740
+ }
112741
+ return void 0;
112742
+ }
112743
+ function truncate2(text) {
112744
+ if (text.length <= MAX_FORMATTED_TEXT_LENGTH) {
112745
+ return text;
112746
+ }
112747
+ return `${text.slice(0, MAX_FORMATTED_TEXT_LENGTH - 3)}...`;
112748
+ }
112749
+ function formatScalar(value) {
112750
+ if (value === null) {
112751
+ return "null";
112752
+ }
112753
+ if (typeof value === "string") {
112754
+ return value.trim().length > 0 ? truncate2(value) : void 0;
112755
+ }
112756
+ if (typeof value === "number" || typeof value === "boolean") {
112757
+ return truncate2(String(value));
112758
+ }
112759
+ return void 0;
112760
+ }
112761
+ function hasSignalValue(value, depth = 0) {
112762
+ if (value === null || value === void 0 || value === false) {
112763
+ return false;
112764
+ }
112765
+ if (typeof value === "string") {
112766
+ return value.trim().length > 0;
112767
+ }
112768
+ if (typeof value === "number") {
112769
+ return Number.isFinite(value);
112770
+ }
112771
+ if (typeof value === "boolean") {
112772
+ return true;
112773
+ }
112774
+ if (depth >= MAX_ERROR_SIGNAL_DEPTH) {
112775
+ return false;
112776
+ }
112777
+ if (Array.isArray(value)) {
112778
+ if (depth >= MAX_FORMATTED_ARRAY_DEPTH) {
112779
+ return false;
112780
+ }
112781
+ return value.slice(0, MAX_FORMATTED_ARRAY_ITEMS).some((item) => {
112782
+ return hasSignalValue(item, depth + 1);
112783
+ });
112784
+ }
112785
+ const record = asRecord(value);
112786
+ if (!record) {
112787
+ return false;
112788
+ }
112789
+ let inspectedFields = 0;
112790
+ for (const key in record) {
112791
+ if (!hasOwnKey(record, key)) {
112792
+ continue;
112793
+ }
112794
+ if (inspectedFields >= MAX_FORMATTED_OBJECT_INSPECTED_FIELDS) {
112795
+ return false;
112796
+ }
112797
+ inspectedFields += 1;
112798
+ if (hasSignalValue(record[key], depth + 1)) {
112799
+ return true;
112800
+ }
112801
+ }
112802
+ return false;
112803
+ }
112804
+ function formatUnknownValue(value, depth = 0) {
112805
+ const scalar = formatScalar(value);
112806
+ if (scalar !== void 0) {
112807
+ return scalar;
112808
+ }
112809
+ if (Array.isArray(value)) {
112810
+ if (depth >= MAX_FORMATTED_ARRAY_DEPTH) {
112811
+ return "...";
112812
+ }
112813
+ const items = value.slice(0, MAX_FORMATTED_ARRAY_ITEMS).map((item) => {
112814
+ return formatUnknownValue(item, depth + 1);
112815
+ }).filter((item) => {
112816
+ return item !== void 0 && item.length > 0;
112817
+ });
112818
+ if (items.length === 0) {
112819
+ return void 0;
112820
+ }
112821
+ const suffix = value.length > MAX_FORMATTED_ARRAY_ITEMS ? ", ..." : "";
112822
+ return `[${items.join(", ")}${suffix}]`;
112823
+ }
112824
+ const record = asRecord(value);
112825
+ if (!record || depth > 0) {
112826
+ return void 0;
112827
+ }
112828
+ const fields = [];
112829
+ let inspectedFields = 0;
112830
+ for (const key in record) {
112831
+ if (!hasOwnKey(record, key)) {
112832
+ continue;
112833
+ }
112834
+ if (fields.length >= MAX_FORMATTED_OBJECT_FIELDS || inspectedFields >= MAX_FORMATTED_OBJECT_INSPECTED_FIELDS) {
112835
+ fields.push("...");
112836
+ break;
112837
+ }
112838
+ inspectedFields += 1;
112839
+ const fieldValue = record[key];
112840
+ const formatted = formatUnknownValue(fieldValue, depth + 1);
112841
+ if (formatted !== void 0) {
112842
+ fields.push(`${key}=${formatted}`);
112843
+ }
112844
+ }
112845
+ return fields.length > 0 ? `{${fields.join(", ")}}` : void 0;
112846
+ }
112847
+ function formatSignalValue(value, includeBoundedPlaceholder = false) {
112848
+ if (value === null || value === void 0 || value === false) {
112849
+ return void 0;
112850
+ }
112851
+ const formatted = formatUnknownValue(value);
112852
+ if (!formatted) {
112853
+ return void 0;
112854
+ }
112855
+ if (hasSignalValue(value)) {
112856
+ return formatted;
112857
+ }
112858
+ return includeBoundedPlaceholder && formatted.includes("...") ? formatted : void 0;
112859
+ }
112860
+ function combineDistinctMessages(first, second) {
112861
+ const messages = [];
112862
+ for (const message of [first, second]) {
112863
+ const trimmed = message?.trim();
112864
+ if (!trimmed) {
112865
+ continue;
112866
+ }
112867
+ const containingIndex = messages.findIndex((existing) => {
112868
+ return existing === trimmed || existing.includes(trimmed);
112869
+ });
112870
+ if (containingIndex !== -1) {
112871
+ continue;
112872
+ }
112873
+ const containedIndex = messages.findIndex((existing) => {
112874
+ return trimmed.includes(existing);
112875
+ });
112876
+ if (containedIndex !== -1) {
112877
+ messages[containedIndex] = trimmed;
112878
+ continue;
112879
+ }
112880
+ messages.push(trimmed);
112881
+ }
112882
+ return messages.length > 0 ? messages.join("\n") : void 0;
112883
+ }
112884
+ function isGenericFailureMessage(message) {
112885
+ const normalized = message.trim().toLowerCase().replace(/[\s.:!?]+$/u, "");
112886
+ return normalized === "error" || normalized === "turn failed" || normalized === "turn interrupted" || normalized === "unknown error" || normalized === "codex error";
112887
+ }
112888
+ function combineResultWithError(result, errorMessage) {
112889
+ if (result === void 0 || result.length === 0) {
112890
+ return errorMessage;
112891
+ }
112892
+ if (!errorMessage) {
112893
+ return result;
112894
+ }
112895
+ const trimmedResult = result.trim();
112896
+ if (!trimmedResult) {
112897
+ return errorMessage;
112898
+ }
112899
+ if (trimmedResult === errorMessage || trimmedResult.includes(errorMessage)) {
112900
+ return result;
112901
+ }
112902
+ if (errorMessage.includes(trimmedResult)) {
112903
+ return errorMessage;
112904
+ }
112905
+ return `${result}
112906
+ ${errorMessage}`;
112907
+ }
112908
+ function formatDetailSuffix(details) {
112909
+ return details.length > 0 ? ` (${details.join("; ")})` : "";
112910
+ }
112911
+ function extractErrorMessage(value, depth = 0) {
112912
+ if (value === null || value === void 0 || value === false) {
112913
+ return void 0;
112914
+ }
112915
+ const direct = trimmedStringValue(value);
112916
+ if (direct) {
112917
+ return direct;
112918
+ }
112919
+ const record = asRecord(value);
112920
+ if (!record) {
112921
+ return hasSignalValue(value, depth) ? formatUnknownValue(value) : void 0;
112922
+ }
112923
+ const message = getFirstString(record, ["message"]) ?? getFirstString(record, ["error", "code", "failureReason"]);
112924
+ const details = [
112925
+ getFirstString(record, ["additional_details", "additionalDetails"]),
112926
+ getFirstString(record, ["codex_error_info", "codexErrorInfo"]),
112927
+ formatSignalValue(record.connectors, message !== void 0)
112928
+ ].filter((detail) => {
112929
+ return detail !== void 0 && detail.length > 0;
112930
+ });
112931
+ if (message) {
112932
+ const uniqueDetails = details.filter((detail) => {
112933
+ return !message.includes(detail);
112934
+ });
112935
+ return `${message}${formatDetailSuffix(uniqueDetails)}`;
112936
+ }
112937
+ if (details.length > 0) {
112938
+ return details.join("; ");
112939
+ }
112940
+ if (depth >= MAX_ERROR_SIGNAL_DEPTH) {
112941
+ return void 0;
112942
+ }
112943
+ const nested = extractErrorMessage(record.error, depth + 1);
112944
+ if (nested) {
112945
+ return nested;
112946
+ }
112947
+ return hasSignalValue(record, depth) ? formatUnknownValue(record) : void 0;
112948
+ }
112949
+ function extractEventErrorMessage(event) {
112950
+ return combineDistinctMessages(
112951
+ trimmedStringValue(event.message),
112952
+ extractErrorMessage(event.error)
112953
+ );
112954
+ }
112955
+ function getTurnRecord(event) {
112956
+ return asRecord(event.turn);
112957
+ }
112958
+ function getTurnId(event) {
112959
+ const topLevelId = getFirstString(event, ["turn_id", "turnId"]);
112960
+ if (topLevelId) {
112961
+ return topLevelId;
112962
+ }
112963
+ const turn = getTurnRecord(event);
112964
+ return turn ? getFirstString(turn, ["id"]) : void 0;
112965
+ }
112966
+ function getTurnStatus(event) {
112967
+ const turn = getTurnRecord(event);
112968
+ return (turn ? getFirstString(turn, ["status"]) : void 0) ?? getFirstString(event, ["status"]);
112969
+ }
112970
+ var FAILED_STATUSES = /* @__PURE__ */ new Set([
112971
+ "aborted",
112972
+ "cancelled",
112973
+ "canceled",
112974
+ "declined",
112975
+ "error",
112976
+ "failed",
112977
+ "interrupted",
112978
+ "timed_out",
112979
+ "timeout"
112980
+ ]);
112981
+ var SUCCESSFUL_TURN_COMPLETION_STATUSES = /* @__PURE__ */ new Set([
112982
+ "completed",
112983
+ "success",
112984
+ "succeeded"
112985
+ ]);
112986
+ function isFailedStatus(status) {
112987
+ return status !== void 0 && FAILED_STATUSES.has(status.toLowerCase());
112988
+ }
112989
+ function isUnsuccessfulTurnCompletionStatus(status) {
112990
+ return status !== void 0 && !SUCCESSFUL_TURN_COMPLETION_STATUSES.has(status.toLowerCase());
112991
+ }
112992
+ function hasExtractableError(value) {
112993
+ return extractErrorMessage(value) !== void 0;
112994
+ }
112995
+ function hasTurnCompletionError(event, turn) {
112996
+ return turn !== null && hasExtractableError(turn.error) || hasExtractableError(event.error);
112997
+ }
112998
+ function getTurnErrorMessage(event, turn) {
112999
+ const turnMessage = turn !== null ? extractErrorMessage(turn.error) : void 0;
113000
+ const eventMessage = extractEventErrorMessage(event);
113001
+ if (turnMessage && eventMessage && isGenericFailureMessage(eventMessage)) {
113002
+ return turnMessage;
113003
+ }
113004
+ return combineDistinctMessages(turnMessage, eventMessage);
113005
+ }
113006
+ function getUsage(event) {
113007
+ const turn = getTurnRecord(event);
113008
+ return asRecord(event.usage) ?? (turn ? asRecord(turn.usage) : null) ?? {};
113009
+ }
113010
+ function getTurnDurationMs(event, turn) {
113011
+ return (turn ? getFirstNumber(turn, ["duration_ms", "durationMs"]) : void 0) ?? getFirstNumber(event, ["duration_ms", "durationMs"]) ?? 0;
113012
+ }
113013
+ function getItem(event) {
113014
+ return asRecord(event.item);
113015
+ }
113016
+ function getItemId(item) {
113017
+ return getFirstString(item, ["id"]);
113018
+ }
113019
+ function getItemType(item) {
113020
+ return getFirstString(item, ["type"]);
113021
+ }
113022
+ function getItemStatus(item) {
113023
+ return getFirstString(item, ["status"]);
113024
+ }
113025
+ function getItemErrorMessage(item) {
113026
+ return extractErrorMessage(item.error);
113027
+ }
113028
+ function shouldRenderGenericItemFailure(eventType, item) {
113029
+ return eventType === "item.completed" && (isFailedStatus(getItemStatus(item)) || getItemErrorMessage(item) !== void 0);
113030
+ }
113031
+ function formatPlanStatus(status) {
113032
+ if (status === "completed") return "completed";
113033
+ if (status === "in_progress") return "in progress";
113034
+ if (status === "pending") return "pending";
113035
+ return status ?? "step";
113036
+ }
113037
+ function formatPlanLines(plan) {
113038
+ if (!Array.isArray(plan)) {
113039
+ return [];
113040
+ }
113041
+ const lines = plan.slice(0, MAX_FORMATTED_PLAN_STEPS).map((step) => {
113042
+ const stepRecord = asRecord(step);
113043
+ if (!stepRecord) {
113044
+ return void 0;
113045
+ }
113046
+ const text = trimmedStringValue(stepRecord.step);
113047
+ if (!text) {
113048
+ return void 0;
113049
+ }
113050
+ const status = formatPlanStatus(trimmedStringValue(stepRecord.status));
113051
+ return `- ${status}: ${text}`;
113052
+ }).filter((line) => {
113053
+ return line !== void 0;
113054
+ });
113055
+ const remaining = plan.length - MAX_FORMATTED_PLAN_STEPS;
113056
+ if (remaining > 0) {
113057
+ lines.push(`- ... +${remaining} more steps`);
113058
+ }
113059
+ return lines;
113060
+ }
113061
+ function formatGenericItem(item) {
113062
+ const itemType = getItemType(item);
113063
+ if (!itemType) {
113064
+ return void 0;
113065
+ }
113066
+ const fields = [itemType];
113067
+ const id = getItemId(item);
113068
+ if (id) {
113069
+ fields.push(`id=${id}`);
113070
+ }
113071
+ const status = getItemStatus(item);
113072
+ if (status) {
113073
+ fields.push(`status=${status}`);
113074
+ }
113075
+ let inspectedFields = 0;
113076
+ for (const key in item) {
113077
+ if (!hasOwnKey(item, key)) {
113078
+ continue;
113079
+ }
113080
+ if (key === "id" || key === "type" || key === "status") {
113081
+ continue;
113082
+ }
113083
+ if (fields.length >= MAX_FORMATTED_OBJECT_FIELDS + 3 || inspectedFields >= MAX_FORMATTED_OBJECT_INSPECTED_FIELDS) {
113084
+ fields.push("...");
113085
+ break;
113086
+ }
113087
+ inspectedFields += 1;
113088
+ const value = item[key];
113089
+ const formatted = formatUnknownValue(value);
113090
+ if (formatted !== void 0) {
113091
+ fields.push(`${key}=${formatted}`);
113092
+ }
113093
+ }
113094
+ return `[item] ${fields.join(" ")}`;
113095
+ }
113096
+ function formatFileChangeAction(kind) {
113097
+ if (kind === "add") return "Created";
113098
+ if (kind === "modify") return "Modified";
113099
+ if (kind === "delete") return "Deleted";
113100
+ return "Changed";
113101
+ }
112681
113102
  var CodexEventParser = class {
112682
113103
  /**
112683
- * Parse a raw Codex CLI JSONL event into a simplified format
112684
- * Returns null if the event type is unknown or malformed
113104
+ * Parse a raw Codex JSONL event into the shared CLI parsed-event format.
113105
+ * Returns null if the event type is unknown or too malformed to display.
112685
113106
  */
112686
113107
  static parse(rawEvent) {
112687
- if (!rawEvent || typeof rawEvent !== "object" || !("type" in rawEvent)) {
113108
+ const event = asRecord(rawEvent);
113109
+ if (!event) {
113110
+ return null;
113111
+ }
113112
+ const eventType = stringValue(event.type);
113113
+ if (!eventType) {
112688
113114
  return null;
112689
113115
  }
112690
- const eventType = rawEvent.type;
112691
113116
  if (eventType === "thread.started") {
112692
- return this.parseThreadStarted(rawEvent);
113117
+ return this.parseThreadStarted(event);
112693
113118
  }
112694
113119
  if (eventType === "turn.completed") {
112695
- return this.parseTurnCompleted(rawEvent);
113120
+ return this.parseTurnCompleted(event);
112696
113121
  }
112697
113122
  if (eventType === "turn.failed") {
112698
- return this.parseTurnFailed(rawEvent);
113123
+ return this.parseTurnFailed(event);
113124
+ }
113125
+ if (eventType === "turn.plan.updated") {
113126
+ return this.parseTurnPlanUpdated(event);
113127
+ }
113128
+ if (eventType === "warning") {
113129
+ return this.parseWarning(event);
112699
113130
  }
112700
113131
  if (eventType.startsWith("item.")) {
112701
- return this.parseItemEvent(rawEvent);
113132
+ return this.parseItemEvent(event, eventType);
112702
113133
  }
112703
113134
  if (eventType === "error") {
112704
- return this.parseErrorEvent(rawEvent);
113135
+ return this.parseErrorEvent(event);
112705
113136
  }
112706
113137
  return null;
112707
113138
  }
112708
113139
  static parseThreadStarted(event) {
113140
+ const threadId2 = getFirstString(event, ["thread_id", "threadId"]);
113141
+ if (!threadId2) {
113142
+ return null;
113143
+ }
112709
113144
  return {
112710
113145
  type: "init",
112711
113146
  timestamp: /* @__PURE__ */ new Date(),
112712
113147
  data: {
112713
113148
  framework: "codex",
112714
- sessionId: event.thread_id,
113149
+ sessionId: threadId2,
112715
113150
  tools: []
112716
113151
  }
112717
113152
  };
112718
113153
  }
112719
113154
  static parseTurnCompleted(event) {
113155
+ const status = getTurnStatus(event);
113156
+ const turn = getTurnRecord(event);
113157
+ const turnId = getTurnId(event);
113158
+ const durationMs = getTurnDurationMs(event, turn);
113159
+ if (isUnsuccessfulTurnCompletionStatus(status) || hasTurnCompletionError(event, turn)) {
113160
+ const result = getTurnErrorMessage(event, turn) ?? (status ? `Turn ${status}` : "Turn failed");
113161
+ return {
113162
+ type: "result",
113163
+ timestamp: /* @__PURE__ */ new Date(),
113164
+ data: {
113165
+ success: false,
113166
+ result,
113167
+ durationMs,
113168
+ numTurns: 1,
113169
+ cost: 0,
113170
+ usage: getUsage(event),
113171
+ ...turnId ? { turnId } : {}
113172
+ }
113173
+ };
113174
+ }
112720
113175
  return {
112721
113176
  type: "result",
112722
113177
  timestamp: /* @__PURE__ */ new Date(),
112723
113178
  data: {
112724
113179
  success: true,
112725
113180
  result: "",
112726
- durationMs: 0,
113181
+ durationMs,
112727
113182
  numTurns: 1,
112728
113183
  cost: 0,
112729
- usage: event.usage || {}
113184
+ usage: getUsage(event),
113185
+ ...turnId ? { turnId } : {}
112730
113186
  }
112731
113187
  };
112732
113188
  }
112733
113189
  static parseTurnFailed(event) {
113190
+ const turn = getTurnRecord(event);
113191
+ const turnId = getTurnId(event);
112734
113192
  return {
112735
113193
  type: "result",
112736
113194
  timestamp: /* @__PURE__ */ new Date(),
112737
113195
  data: {
112738
113196
  success: false,
112739
- result: event.error || "Turn failed",
112740
- durationMs: 0,
113197
+ result: getTurnErrorMessage(event, turn) ?? "Turn failed",
113198
+ durationMs: getTurnDurationMs(event, turn),
112741
113199
  numTurns: 1,
112742
113200
  cost: 0,
112743
- usage: {}
113201
+ usage: getUsage(event),
113202
+ ...turnId ? { turnId } : {}
113203
+ }
113204
+ };
113205
+ }
113206
+ static parseTurnPlanUpdated(event) {
113207
+ const lines = formatPlanLines(event.plan);
113208
+ const explanation = trimmedStringValue(event.explanation);
113209
+ if (lines.length === 0 && !explanation) {
113210
+ return null;
113211
+ }
113212
+ return {
113213
+ type: "text",
113214
+ timestamp: /* @__PURE__ */ new Date(),
113215
+ data: {
113216
+ text: ["[plan]", explanation, ...lines].filter((line) => {
113217
+ return line !== void 0 && line.length > 0;
113218
+ }).join("\n")
112744
113219
  }
112745
113220
  };
112746
113221
  }
112747
- static parseItemEvent(event) {
112748
- const item = event.item;
113222
+ static parseWarning(event) {
113223
+ const message = extractEventErrorMessage(event);
113224
+ if (!message) {
113225
+ return null;
113226
+ }
113227
+ return {
113228
+ type: "text",
113229
+ timestamp: /* @__PURE__ */ new Date(),
113230
+ data: { text: `[warning] ${message}` }
113231
+ };
113232
+ }
113233
+ static parseItemEvent(event, eventType) {
113234
+ const item = getItem(event);
112749
113235
  if (!item) {
112750
113236
  return null;
112751
113237
  }
112752
- const itemType = item.type;
112753
- if (itemType === "agent_message" && item.text) {
112754
- return { type: "text", timestamp: /* @__PURE__ */ new Date(), data: { text: item.text } };
113238
+ const itemType = getItemType(item);
113239
+ if (!itemType) {
113240
+ return null;
113241
+ }
113242
+ if (itemType === "agent_message") {
113243
+ return this.parseTextItem(eventType, item, (text) => {
113244
+ return text;
113245
+ });
112755
113246
  }
112756
113247
  if (itemType === "command_execution") {
112757
- return this.parseCommandExecution(event);
113248
+ return this.parseCommandExecution(eventType, item);
112758
113249
  }
112759
113250
  if (itemType === "file_edit" || itemType === "file_write") {
112760
- return this.parseFileEditOrWrite(event);
113251
+ return this.parseFileEditOrWrite(eventType, item);
112761
113252
  }
112762
113253
  if (itemType === "file_read") {
112763
- return this.parseFileRead(event);
113254
+ return this.parseFileRead(eventType, item);
112764
113255
  }
112765
113256
  if (itemType === "file_change") {
112766
113257
  return this.parseFileChange(item);
112767
113258
  }
112768
- if (itemType === "reasoning" && item.text) {
113259
+ if (itemType === "reasoning") {
113260
+ return this.parseTextItem(eventType, item, (text) => {
113261
+ return `[thinking] ${text}`;
113262
+ });
113263
+ }
113264
+ if (itemType === "plan") {
113265
+ return this.parseTextItem(eventType, item, (text) => {
113266
+ return `[plan]
113267
+ ${text}`;
113268
+ });
113269
+ }
113270
+ if (eventType === "item.completed") {
113271
+ return this.parseGenericCompletedItem(item);
113272
+ }
113273
+ return null;
113274
+ }
113275
+ static parseTextItem(eventType, item, formatText) {
113276
+ const text = trimmedStringValue(item.text);
113277
+ if (text) {
112769
113278
  return {
112770
113279
  type: "text",
112771
113280
  timestamp: /* @__PURE__ */ new Date(),
112772
- data: { text: `[thinking] ${item.text}` }
113281
+ data: { text: formatText(text) }
112773
113282
  };
112774
113283
  }
112775
- return null;
113284
+ return shouldRenderGenericItemFailure(eventType, item) ? this.parseGenericCompletedItem(item) : null;
112776
113285
  }
112777
- static parseCommandExecution(event) {
112778
- const item = event.item;
112779
- if (event.type === "item.started" && item.command) {
113286
+ static parseGenericCompletedItem(item) {
113287
+ const text = formatGenericItem(item);
113288
+ return text ? { type: "text", timestamp: /* @__PURE__ */ new Date(), data: { text } } : null;
113289
+ }
113290
+ static parseCommandExecution(eventType, item) {
113291
+ const itemId = getItemId(item);
113292
+ const command = trimmedStringValue(item.command);
113293
+ if (!itemId) {
113294
+ return null;
113295
+ }
113296
+ if (eventType === "item.started" && command) {
112780
113297
  return {
112781
113298
  type: "tool_use",
112782
113299
  timestamp: /* @__PURE__ */ new Date(),
112783
113300
  data: {
112784
113301
  tool: "Bash",
112785
- toolUseId: item.id,
112786
- input: { command: item.command }
113302
+ toolUseId: itemId,
113303
+ input: { command }
112787
113304
  }
112788
113305
  };
112789
113306
  }
112790
- if (event.type === "item.completed") {
112791
- const output = item.aggregated_output ?? item.output ?? "";
113307
+ if (eventType === "item.completed") {
113308
+ const output = nonEmptyStringValue(item.aggregated_output) ?? nonEmptyStringValue(item.output) ?? "";
113309
+ const status = getItemStatus(item);
113310
+ const exitCode = numberValue(item.exit_code);
113311
+ const errorMessage = getItemErrorMessage(item);
113312
+ const isError2 = (exitCode !== void 0 ? exitCode !== 0 : false) || isFailedStatus(status) || errorMessage !== void 0;
112792
113313
  return {
112793
113314
  type: "tool_result",
112794
113315
  timestamp: /* @__PURE__ */ new Date(),
112795
113316
  data: {
112796
- toolUseId: item.id,
112797
- result: output,
112798
- isError: item.exit_code !== 0
113317
+ tool: "Bash",
113318
+ toolUseId: itemId,
113319
+ input: command ? { command } : {},
113320
+ result: combineResultWithError(output, errorMessage) ?? (isFailedStatus(status) ? `Command ${status}` : ""),
113321
+ isError: isError2
112799
113322
  }
112800
113323
  };
112801
113324
  }
112802
113325
  return null;
112803
113326
  }
112804
- static parseFileEditOrWrite(event) {
112805
- const item = event.item;
112806
- if (event.type === "item.started" && item.path) {
113327
+ static parseFileEditOrWrite(eventType, item) {
113328
+ const itemId = getItemId(item);
113329
+ const path4 = trimmedStringValue(item.path);
113330
+ if (!itemId) {
113331
+ return null;
113332
+ }
113333
+ if (eventType === "item.started" && path4) {
112807
113334
  return {
112808
113335
  type: "tool_use",
112809
113336
  timestamp: /* @__PURE__ */ new Date(),
112810
113337
  data: {
112811
- tool: item.type === "file_edit" ? "Edit" : "Write",
112812
- toolUseId: item.id,
112813
- input: { file_path: item.path }
113338
+ tool: getItemType(item) === "file_edit" ? "Edit" : "Write",
113339
+ toolUseId: itemId,
113340
+ input: { file_path: path4 }
112814
113341
  }
112815
113342
  };
112816
113343
  }
112817
- if (event.type === "item.completed") {
113344
+ if (eventType === "item.completed") {
113345
+ const status = getItemStatus(item);
113346
+ const tool = getItemType(item) === "file_edit" ? "Edit" : "Write";
113347
+ const errorMessage = getItemErrorMessage(item);
112818
113348
  return {
112819
113349
  type: "tool_result",
112820
113350
  timestamp: /* @__PURE__ */ new Date(),
112821
113351
  data: {
112822
- toolUseId: item.id,
112823
- result: item.diff || "File operation completed",
112824
- isError: false
113352
+ tool,
113353
+ toolUseId: itemId,
113354
+ input: path4 ? { file_path: path4 } : {},
113355
+ result: combineResultWithError(
113356
+ nonEmptyStringValue(item.diff),
113357
+ errorMessage
113358
+ ) ?? (isFailedStatus(status) ? `File operation ${status}` : "File operation completed"),
113359
+ isError: isFailedStatus(status) || errorMessage !== void 0
112825
113360
  }
112826
113361
  };
112827
113362
  }
112828
113363
  return null;
112829
113364
  }
112830
- static parseFileRead(event) {
112831
- const item = event.item;
112832
- if (event.type === "item.started" && item.path) {
113365
+ static parseFileRead(eventType, item) {
113366
+ const itemId = getItemId(item);
113367
+ const path4 = trimmedStringValue(item.path);
113368
+ if (!itemId) {
113369
+ return null;
113370
+ }
113371
+ if (eventType === "item.started" && path4) {
112833
113372
  return {
112834
113373
  type: "tool_use",
112835
113374
  timestamp: /* @__PURE__ */ new Date(),
112836
113375
  data: {
112837
113376
  tool: "Read",
112838
- toolUseId: item.id,
112839
- input: { file_path: item.path }
113377
+ toolUseId: itemId,
113378
+ input: { file_path: path4 }
112840
113379
  }
112841
113380
  };
112842
113381
  }
112843
- if (event.type === "item.completed") {
113382
+ if (eventType === "item.completed") {
113383
+ const status = getItemStatus(item);
113384
+ const output = nonEmptyStringValue(item.output);
113385
+ const errorMessage = getItemErrorMessage(item);
112844
113386
  return {
112845
113387
  type: "tool_result",
112846
113388
  timestamp: /* @__PURE__ */ new Date(),
112847
113389
  data: {
112848
- toolUseId: item.id,
112849
- result: "File read completed",
112850
- isError: false
113390
+ tool: "Read",
113391
+ toolUseId: itemId,
113392
+ input: path4 ? { file_path: path4 } : {},
113393
+ result: combineResultWithError(output, errorMessage) ?? (isFailedStatus(status) ? `File read ${status}` : "File read completed"),
113394
+ isError: isFailedStatus(status) || errorMessage !== void 0
112851
113395
  }
112852
113396
  };
112853
113397
  }
112854
113398
  return null;
112855
113399
  }
112856
113400
  static parseFileChange(item) {
112857
- if (!item.changes || item.changes.length === 0) {
113401
+ const status = getItemStatus(item);
113402
+ const errorMessage = getItemErrorMessage(item);
113403
+ const lines = Array.isArray(item.changes) ? item.changes.slice(0, MAX_FORMATTED_FILE_CHANGES).map((change) => {
113404
+ const changeRecord = asRecord(change);
113405
+ if (!changeRecord) {
113406
+ return void 0;
113407
+ }
113408
+ const path4 = trimmedStringValue(changeRecord.path);
113409
+ if (!path4) {
113410
+ return void 0;
113411
+ }
113412
+ const action = formatFileChangeAction(
113413
+ trimmedStringValue(changeRecord.kind)
113414
+ );
113415
+ return `${action}: ${path4}`;
113416
+ }).filter((line) => {
113417
+ return line !== void 0;
113418
+ }) : [];
113419
+ if (Array.isArray(item.changes) && item.changes.length > MAX_FORMATTED_FILE_CHANGES) {
113420
+ lines.push(
113421
+ `... +${item.changes.length - MAX_FORMATTED_FILE_CHANGES} more changes`
113422
+ );
113423
+ }
113424
+ if (lines.length === 0 && !isFailedStatus(status) && !errorMessage) {
112858
113425
  return null;
112859
113426
  }
112860
- const changes = item.changes.map((c101) => {
112861
- const action = c101.kind === "add" ? "Created" : c101.kind === "modify" ? "Modified" : "Deleted";
112862
- return `${action}: ${c101.path}`;
112863
- }).join("\n");
113427
+ const statusLine = isFailedStatus(status) ? `Status: ${status}` : void 0;
113428
+ const errorLine = errorMessage ? `Error: ${errorMessage}` : void 0;
112864
113429
  return {
112865
113430
  type: "text",
112866
113431
  timestamp: /* @__PURE__ */ new Date(),
112867
- data: { text: `[files]
112868
- ${changes}` }
113432
+ data: {
113433
+ text: ["[files]", statusLine, errorLine, ...lines].filter((line) => {
113434
+ return line !== void 0 && line.length > 0;
113435
+ }).join("\n")
113436
+ }
112869
113437
  };
112870
113438
  }
112871
113439
  static parseErrorEvent(event) {
113440
+ const turn = getTurnRecord(event);
113441
+ const turnId = getTurnId(event);
113442
+ const hasTurnContext = turn !== null || turnId !== void 0;
112872
113443
  return {
112873
113444
  type: "result",
112874
113445
  timestamp: /* @__PURE__ */ new Date(),
112875
113446
  data: {
112876
113447
  success: false,
112877
- result: event.message || event.error || "Unknown error",
112878
- durationMs: 0,
112879
- numTurns: 0,
113448
+ result: getTurnErrorMessage(event, turn) ?? "Unknown error",
113449
+ durationMs: getTurnDurationMs(event, turn),
113450
+ numTurns: hasTurnContext ? 1 : 0,
112880
113451
  cost: 0,
112881
- usage: {}
113452
+ usage: getUsage(event),
113453
+ ...turnId ? { turnId } : {}
112882
113454
  }
112883
113455
  };
112884
113456
  }
@@ -112894,7 +113466,7 @@ function parseEvent(rawEvent, framework) {
112894
113466
  }
112895
113467
 
112896
113468
  // src/lib/events/event-stream-normalizer.ts
112897
- function asRecord(rawEvent) {
113469
+ function asRecord2(rawEvent) {
112898
113470
  if (!rawEvent || typeof rawEvent !== "object") {
112899
113471
  return null;
112900
113472
  }
@@ -112904,13 +113476,72 @@ function getEventType(rawEvent) {
112904
113476
  const eventType = rawEvent?.type;
112905
113477
  return typeof eventType === "string" ? eventType : void 0;
112906
113478
  }
113479
+ function stringData(value) {
113480
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
113481
+ }
113482
+ function isFailureResult(event) {
113483
+ return event?.type === "result" && event.data.success === false;
113484
+ }
113485
+ function isTopLevelCodexError(eventType, parsed) {
113486
+ return eventType === "error" && isFailureResult(parsed);
113487
+ }
113488
+ function isTerminalCodexFailure(eventType, parsed) {
113489
+ if (!isFailureResult(parsed)) {
113490
+ return false;
113491
+ }
113492
+ return eventType === "turn.failed" || eventType === "turn.completed";
113493
+ }
113494
+ function getParsedTurnId(event) {
113495
+ return stringData(event.data.turnId);
113496
+ }
113497
+ function getResultText(event) {
113498
+ return stringData(event.data.result);
113499
+ }
113500
+ function combineDistinctMessages2(first, second) {
113501
+ const messages = [];
113502
+ for (const message of [first, second]) {
113503
+ if (!message) {
113504
+ continue;
113505
+ }
113506
+ const containingIndex = messages.findIndex((existing) => {
113507
+ return existing === message || existing.includes(message);
113508
+ });
113509
+ if (containingIndex !== -1) {
113510
+ continue;
113511
+ }
113512
+ const containedIndex = messages.findIndex((existing) => {
113513
+ return message.includes(existing);
113514
+ });
113515
+ if (containedIndex !== -1) {
113516
+ messages[containedIndex] = message;
113517
+ continue;
113518
+ }
113519
+ messages.push(message);
113520
+ }
113521
+ return messages.length > 0 ? messages.join("\n") : void 0;
113522
+ }
113523
+ function attachFramework(parsed, framework) {
113524
+ if (!parsed || !framework || parsed.data.framework !== void 0) {
113525
+ return parsed;
113526
+ }
113527
+ return {
113528
+ ...parsed,
113529
+ data: {
113530
+ ...parsed.data,
113531
+ framework
113532
+ }
113533
+ };
113534
+ }
112907
113535
  var EventStreamNormalizer = class {
112908
113536
  pendingCodexError = null;
112909
113537
  process(rawEvent, framework, timestamp) {
112910
113538
  const isCodex = framework === "codex";
112911
- const rawRecord = asRecord(rawEvent);
113539
+ const rawRecord = asRecord2(rawEvent);
112912
113540
  const eventType = getEventType(rawRecord);
112913
- const parsed = rawRecord ? parseEvent(rawRecord, framework) : null;
113541
+ const parsed = attachFramework(
113542
+ rawRecord ? parseEvent(rawRecord, framework) : null,
113543
+ framework
113544
+ );
112914
113545
  if (parsed && timestamp) {
112915
113546
  parsed.timestamp = timestamp;
112916
113547
  }
@@ -112921,19 +113552,44 @@ var EventStreamNormalizer = class {
112921
113552
  }
112922
113553
  return output2;
112923
113554
  }
112924
- if (eventType === "error" && parsed?.type === "result") {
113555
+ if (isTopLevelCodexError(eventType, parsed)) {
112925
113556
  const output2 = this.flush();
112926
113557
  this.pendingCodexError = parsed;
112927
113558
  return output2;
112928
113559
  }
112929
- if (eventType === "turn.failed") {
113560
+ if (isTerminalCodexFailure(eventType, parsed)) {
113561
+ if (this.pendingCodexError) {
113562
+ const pendingTurnId = getParsedTurnId(this.pendingCodexError);
113563
+ const terminalTurnId = getParsedTurnId(parsed);
113564
+ const shouldCollapse = !pendingTurnId || terminalTurnId !== void 0 && pendingTurnId === terminalTurnId;
113565
+ if (shouldCollapse) {
113566
+ const mergedResult = combineDistinctMessages2(
113567
+ getResultText(this.pendingCodexError),
113568
+ getResultText(parsed)
113569
+ );
113570
+ this.pendingCodexError = null;
113571
+ return [
113572
+ {
113573
+ ...parsed,
113574
+ data: {
113575
+ ...parsed.data,
113576
+ ...mergedResult ? { result: mergedResult } : {}
113577
+ }
113578
+ }
113579
+ ];
113580
+ }
113581
+ const output2 = this.flush();
113582
+ output2.push(parsed);
113583
+ return output2;
113584
+ }
112930
113585
  this.pendingCodexError = null;
112931
- return parsed ? [parsed] : [];
113586
+ return [parsed];
112932
113587
  }
112933
- const output = this.flush();
112934
- if (parsed) {
112935
- output.push(parsed);
113588
+ if (!parsed) {
113589
+ return [];
112936
113590
  }
113591
+ const output = this.flush();
113592
+ output.push(parsed);
112937
113593
  return output;
112938
113594
  }
112939
113595
  flush() {
@@ -112946,18 +113602,42 @@ var EventStreamNormalizer = class {
112946
113602
  }
112947
113603
  };
112948
113604
 
113605
+ // src/lib/utils/time-format.ts
113606
+ init_esm_shims();
113607
+ function formatIsoTimestamp(value) {
113608
+ const timestamp = value instanceof Date ? value : new Date(value);
113609
+ if (!Number.isFinite(timestamp.getTime())) {
113610
+ return "invalid-date";
113611
+ }
113612
+ return timestamp.toISOString().replace(/\.\d{3}Z$/, "Z");
113613
+ }
113614
+
112949
113615
  // src/lib/events/event-renderer.ts
112950
113616
  init_esm_shims();
112951
113617
 
112952
113618
  // src/lib/events/tool-formatters.ts
112953
113619
  init_esm_shims();
113620
+ var MAX_FORMATTED_TODOS = 20;
112954
113621
  function pluralize(count, singular, plural) {
112955
113622
  return count === 1 ? singular : plural;
112956
113623
  }
112957
- function truncate2(text, maxLength) {
113624
+ function truncate3(text, maxLength) {
112958
113625
  if (text.length <= maxLength) return text;
112959
113626
  return text.slice(0, maxLength - 3) + "...";
112960
113627
  }
113628
+ function displayValue(value) {
113629
+ return value === null || value === void 0 ? "" : String(value);
113630
+ }
113631
+ function nonEmptyDisplayValue(value) {
113632
+ const display = displayValue(value);
113633
+ return display.length > 0 ? display : void 0;
113634
+ }
113635
+ function recordValue(value) {
113636
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
113637
+ return null;
113638
+ }
113639
+ return value;
113640
+ }
112961
113641
  function formatToolHeader(data) {
112962
113642
  const { tool, input } = data;
112963
113643
  const headline = getToolHeadline(tool, input);
@@ -112965,31 +113645,31 @@ function formatToolHeader(data) {
112965
113645
  }
112966
113646
  var toolHeadlineFormatters = {
112967
113647
  Read: (input) => {
112968
- return `Read${source_default.dim(`(${String(input.file_path || "")})`)}`;
113648
+ return `Read${source_default.dim(`(${displayValue(input.file_path)})`)}`;
112969
113649
  },
112970
113650
  Edit: (input) => {
112971
- return `Edit${source_default.dim(`(${String(input.file_path || "")})`)}`;
113651
+ return `Edit${source_default.dim(`(${displayValue(input.file_path)})`)}`;
112972
113652
  },
112973
113653
  Write: (input) => {
112974
- return `Write${source_default.dim(`(${String(input.file_path || "")})`)}`;
113654
+ return `Write${source_default.dim(`(${displayValue(input.file_path)})`)}`;
112975
113655
  },
112976
113656
  Bash: (input) => {
112977
- return `Bash${source_default.dim(`(${truncate2(String(input.command || ""), 60)})`)}`;
113657
+ return `Bash${source_default.dim(`(${truncate3(displayValue(input.command), 60)})`)}`;
112978
113658
  },
112979
113659
  Glob: (input) => {
112980
- return `Glob${source_default.dim(`(${String(input.pattern || "")})`)}`;
113660
+ return `Glob${source_default.dim(`(${displayValue(input.pattern)})`)}`;
112981
113661
  },
112982
113662
  Grep: (input) => {
112983
- return `Grep${source_default.dim(`(${String(input.pattern || "")})`)}`;
113663
+ return `Grep${source_default.dim(`(${displayValue(input.pattern)})`)}`;
112984
113664
  },
112985
113665
  Task: (input) => {
112986
- return `Task${source_default.dim(`(${truncate2(String(input.description || ""), 60)})`)}`;
113666
+ return `Task${source_default.dim(`(${truncate3(displayValue(input.description), 60)})`)}`;
112987
113667
  },
112988
113668
  WebFetch: (input) => {
112989
- return `WebFetch${source_default.dim(`(${truncate2(String(input.url || ""), 60)})`)}`;
113669
+ return `WebFetch${source_default.dim(`(${truncate3(displayValue(input.url), 60)})`)}`;
112990
113670
  },
112991
113671
  WebSearch: (input) => {
112992
- return `WebSearch${source_default.dim(`(${truncate2(String(input.query || ""), 60)})`)}`;
113672
+ return `WebSearch${source_default.dim(`(${truncate3(displayValue(input.query), 60)})`)}`;
112993
113673
  },
112994
113674
  TodoWrite: () => {
112995
113675
  return "TodoWrite";
@@ -113003,28 +113683,18 @@ function formatToolResult(toolUse, result, verbose) {
113003
113683
  const { tool, input } = toolUse;
113004
113684
  const { result: resultText, isError: isError2 } = result;
113005
113685
  const lines = [];
113006
- if (tool === "Read" && !isError2 && resultText) {
113007
- const readLines = formatReadContent(resultText, verbose);
113008
- lines.push(...readLines);
113009
- return lines;
113010
- }
113011
- if (tool === "TodoWrite" && !isError2) {
113012
- const todoLines = formatTodoList(input);
113013
- lines.push(...todoLines);
113014
- return lines;
113015
- }
113016
- if (tool === "Edit" && !isError2) {
113017
- const editLines = formatEditDiff(input, verbose);
113018
- lines.push(...editLines);
113019
- return lines;
113020
- }
113021
- if (tool === "Write" && !isError2) {
113022
- const writeLines = formatWritePreview(input, verbose);
113023
- lines.push(...writeLines);
113024
- return lines;
113686
+ const specialLines = formatSpecialToolResult(
113687
+ tool,
113688
+ input,
113689
+ resultText,
113690
+ isError2,
113691
+ verbose
113692
+ );
113693
+ if (specialLines) {
113694
+ return specialLines;
113025
113695
  }
113026
113696
  if (isError2) {
113027
- const errorMsg = resultText ? truncate2(resultText, 80) : "Error";
113697
+ const errorMsg = resultText ? truncate3(resultText, 80) : "Error";
113028
113698
  lines.push(`\u2514 \u2717 ${source_default.dim(errorMsg)}`);
113029
113699
  return lines;
113030
113700
  }
@@ -113053,6 +113723,30 @@ function formatToolResult(toolUse, result, verbose) {
113053
113723
  }
113054
113724
  return lines;
113055
113725
  }
113726
+ function formatSpecialToolResult(tool, input, resultText, isError2, verbose) {
113727
+ if (isError2) {
113728
+ return null;
113729
+ }
113730
+ if (tool === "Read" && resultText) {
113731
+ return formatReadContent(resultText, verbose);
113732
+ }
113733
+ if (tool === "TodoWrite") {
113734
+ return formatTodoList(input);
113735
+ }
113736
+ if (tool === "Edit" && hasClaudeEditInput(input)) {
113737
+ return formatEditDiff(input, verbose);
113738
+ }
113739
+ if (tool === "Write" && hasClaudeWriteInput(input)) {
113740
+ return formatWritePreview(input, verbose);
113741
+ }
113742
+ return null;
113743
+ }
113744
+ function hasClaudeEditInput(input) {
113745
+ return typeof input.old_string === "string" || typeof input.new_string === "string";
113746
+ }
113747
+ function hasClaudeWriteInput(input) {
113748
+ return typeof input.content === "string";
113749
+ }
113056
113750
  function formatReadContent(resultText, verbose) {
113057
113751
  const lines = [];
113058
113752
  const rawLines = resultText.split("\n");
@@ -113064,9 +113758,7 @@ function formatReadContent(resultText, verbose) {
113064
113758
  contentLines.push(match[1] ?? "");
113065
113759
  }
113066
113760
  }
113067
- const displayLines = contentLines.length > 0 ? contentLines : rawLines.filter((line) => {
113068
- return line.trim().length > 0;
113069
- });
113761
+ const displayLines = contentLines.length > 0 ? contentLines : rawLines;
113070
113762
  const totalLines = displayLines.length;
113071
113763
  if (totalLines === 0) {
113072
113764
  lines.push(`\u2514 \u2713 ${source_default.dim("(empty)")}`);
@@ -113094,7 +113786,7 @@ function formatReadContent(resultText, verbose) {
113094
113786
  }
113095
113787
  function formatWritePreview(input, verbose) {
113096
113788
  const lines = [];
113097
- const content = String(input.content || "");
113789
+ const content = displayValue(input.content);
113098
113790
  const contentLines = content.split("\n");
113099
113791
  const totalLines = contentLines.length;
113100
113792
  if (verbose) {
@@ -113119,8 +113811,8 @@ function formatWritePreview(input, verbose) {
113119
113811
  }
113120
113812
  function formatEditDiff(input, verbose) {
113121
113813
  const lines = [];
113122
- const oldString = String(input.old_string || "");
113123
- const newString = String(input.new_string || "");
113814
+ const oldString = displayValue(input.old_string);
113815
+ const newString = displayValue(input.new_string);
113124
113816
  const oldLines = oldString.split("\n");
113125
113817
  const newLines = newString.split("\n");
113126
113818
  const removed = oldLines.length;
@@ -113139,7 +113831,7 @@ function formatEditDiff(input, verbose) {
113139
113831
  const showOld = Math.min(previewLimit, oldLines.length);
113140
113832
  const showNew = Math.min(previewLimit, newLines.length);
113141
113833
  for (let i = 0; i < showOld; i++) {
113142
- lines.push(` - ${source_default.dim(truncate2(oldLines[i] ?? "", 60))}`);
113834
+ lines.push(` - ${source_default.dim(truncate3(oldLines[i] ?? "", 60))}`);
113143
113835
  }
113144
113836
  const remainingOld = oldLines.length - previewLimit;
113145
113837
  if (remainingOld > 0) {
@@ -113148,7 +113840,7 @@ function formatEditDiff(input, verbose) {
113148
113840
  );
113149
113841
  }
113150
113842
  for (let i = 0; i < showNew; i++) {
113151
- lines.push(` + ${source_default.dim(truncate2(newLines[i] ?? "", 60))}`);
113843
+ lines.push(` + ${source_default.dim(truncate3(newLines[i] ?? "", 60))}`);
113152
113844
  }
113153
113845
  const remainingNew = newLines.length - previewLimit;
113154
113846
  if (remainingNew > 0) {
@@ -113162,19 +113854,30 @@ function formatEditDiff(input, verbose) {
113162
113854
  function formatTodoList(input) {
113163
113855
  const lines = [];
113164
113856
  const todos = input.todos;
113165
- if (!todos || !Array.isArray(todos)) {
113857
+ if (!Array.isArray(todos)) {
113166
113858
  lines.push("\u2514 \u2713 Done");
113167
113859
  return lines;
113168
113860
  }
113169
- for (let i = 0; i < todos.length; i++) {
113170
- const todo = todos[i];
113171
- const content = todo.content || "Unknown task";
113172
- const status = todo.status || "pending";
113861
+ if (todos.length === 0) {
113862
+ lines.push("\u2514 \u2713 Done");
113863
+ return lines;
113864
+ }
113865
+ const displayedTodos = todos.slice(0, MAX_FORMATTED_TODOS);
113866
+ for (let i = 0; i < displayedTodos.length; i++) {
113867
+ const todo = recordValue(displayedTodos[i]);
113868
+ const content = nonEmptyDisplayValue(todo?.content) ?? "Unknown task";
113869
+ const status = nonEmptyDisplayValue(todo?.status) ?? "pending";
113173
113870
  const icon = getTodoStatusIcon(status);
113174
113871
  const styledContent = formatTodoContent(content, status);
113175
113872
  const prefix = i === 0 ? "\u2514 " : " ";
113176
113873
  lines.push(`${prefix}${icon} ${styledContent}`);
113177
113874
  }
113875
+ const remaining = todos.length - MAX_FORMATTED_TODOS;
113876
+ if (remaining > 0) {
113877
+ lines.push(
113878
+ ` ${source_default.dim(`\u2026 +${remaining} ${pluralize(remaining, "task", "tasks")} (vm0 logs <runId> to see all)`)}`
113879
+ );
113880
+ }
113178
113881
  return lines;
113179
113882
  }
113180
113883
  function getTodoStatusIcon(status) {
@@ -113201,8 +113904,23 @@ function formatTodoContent(content, status) {
113201
113904
  }
113202
113905
 
113203
113906
  // src/lib/events/event-renderer.ts
113907
+ function recordData(value) {
113908
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
113909
+ return {};
113910
+ }
113911
+ return value;
113912
+ }
113913
+ function displayString(value) {
113914
+ return value === null || value === void 0 ? "" : String(value);
113915
+ }
113916
+ function displayNonNegativeNumber(value) {
113917
+ const number = typeof value === "number" ? value : typeof value === "string" && value.trim().length > 0 ? Number(value) : void 0;
113918
+ return number !== void 0 && Number.isFinite(number) && number >= 0 ? number : 0;
113919
+ }
113204
113920
  var EventRenderer = class _EventRenderer {
113205
113921
  pendingToolUse = /* @__PURE__ */ new Map();
113922
+ ambiguousToolUseIds = /* @__PURE__ */ new Set();
113923
+ ambiguousRenderedToolUses = /* @__PURE__ */ new Map();
113206
113924
  options;
113207
113925
  lastEventType = null;
113208
113926
  frameworkDisplayName = "Agent";
@@ -113226,7 +113944,7 @@ var EventRenderer = class _EventRenderer {
113226
113944
  * Format timestamp for display (without milliseconds, matching metrics format)
113227
113945
  */
113228
113946
  static formatTimestamp(timestamp) {
113229
- return timestamp.toISOString().replace(/\.\d{3}Z$/, "Z");
113947
+ return formatIsoTimestamp(timestamp);
113230
113948
  }
113231
113949
  /**
113232
113950
  * Render a parsed event to console
@@ -113235,9 +113953,11 @@ var EventRenderer = class _EventRenderer {
113235
113953
  const timestampPrefix = this.options.showTimestamp ? `[${_EventRenderer.formatTimestamp(event.timestamp)}] ` : "";
113236
113954
  switch (event.type) {
113237
113955
  case "init":
113956
+ this.renderPendingToolUses();
113238
113957
  this.renderInit(event, timestampPrefix);
113239
113958
  break;
113240
113959
  case "text":
113960
+ this.renderPendingToolUses();
113241
113961
  this.renderText(event, timestampPrefix);
113242
113962
  break;
113243
113963
  case "tool_use":
@@ -113247,10 +113967,30 @@ var EventRenderer = class _EventRenderer {
113247
113967
  this.handleToolResult(event, timestampPrefix);
113248
113968
  break;
113249
113969
  case "result":
113970
+ this.renderPendingToolUses();
113250
113971
  this.renderResult(event, timestampPrefix);
113251
113972
  break;
113252
113973
  }
113253
113974
  }
113975
+ /**
113976
+ * Render any buffered display state that cannot wait for a future event.
113977
+ */
113978
+ flush() {
113979
+ this.renderPendingToolUses();
113980
+ this.pendingToolUse.clear();
113981
+ this.ambiguousToolUseIds.clear();
113982
+ this.ambiguousRenderedToolUses.clear();
113983
+ }
113984
+ renderPendingToolUses() {
113985
+ for (const pending of this.pendingToolUse.values()) {
113986
+ if (pending.rendered) {
113987
+ continue;
113988
+ }
113989
+ const { toolUse, prefix } = pending;
113990
+ this.renderToolUseOnly(toolUse, prefix);
113991
+ pending.rendered = true;
113992
+ }
113993
+ }
113254
113994
  /**
113255
113995
  * Render run completed state
113256
113996
  * Note: This is run lifecycle status, not an event
@@ -113305,12 +114045,30 @@ var EventRenderer = class _EventRenderer {
113305
114045
  * or render immediately (when not buffered, e.g., historical log viewing)
113306
114046
  */
113307
114047
  handleToolUse(event, prefix) {
113308
- const toolUseId = String(event.data.toolUseId || "");
113309
- const tool = String(event.data.tool || "");
113310
- const input = event.data.input || {};
114048
+ const toolUseId = displayString(event.data.toolUseId);
114049
+ const tool = displayString(event.data.tool);
114050
+ const input = recordData(event.data.input);
113311
114051
  const toolUseData = { tool, input };
113312
- if (this.options.buffered !== false) {
113313
- this.pendingToolUse.set(toolUseId, { toolUse: toolUseData, prefix });
114052
+ if (this.options.buffered !== false && toolUseId.length > 0) {
114053
+ const existing = this.pendingToolUse.get(toolUseId);
114054
+ if (existing || this.ambiguousToolUseIds.has(toolUseId)) {
114055
+ if (existing) {
114056
+ if (!existing.rendered) {
114057
+ this.renderToolUseOnly(existing.toolUse, existing.prefix);
114058
+ }
114059
+ this.rememberAmbiguousRenderedToolUse(toolUseId, existing.toolUse);
114060
+ }
114061
+ this.pendingToolUse.delete(toolUseId);
114062
+ this.ambiguousToolUseIds.add(toolUseId);
114063
+ this.renderToolUseOnly(toolUseData, prefix);
114064
+ this.rememberAmbiguousRenderedToolUse(toolUseId, toolUseData);
114065
+ return;
114066
+ }
114067
+ this.pendingToolUse.set(toolUseId, {
114068
+ toolUse: toolUseData,
114069
+ prefix,
114070
+ rendered: false
114071
+ });
113314
114072
  } else {
113315
114073
  this.renderToolUseOnly(toolUseData, prefix);
113316
114074
  }
@@ -113338,14 +114096,69 @@ var EventRenderer = class _EventRenderer {
113338
114096
  * Handle tool_result event - lookup buffered tool_use and render grouped
113339
114097
  */
113340
114098
  handleToolResult(event, prefix) {
113341
- const toolUseId = String(event.data.toolUseId || "");
113342
- const result = String(event.data.result || "");
114099
+ const toolUseId = displayString(event.data.toolUseId);
114100
+ const result = displayString(event.data.result);
113343
114101
  const isError2 = Boolean(event.data.isError);
114102
+ if (toolUseId.length > 0 && this.ambiguousToolUseIds.has(toolUseId)) {
114103
+ const orphanToolUse2 = this.getToolUseFromResultEvent(event);
114104
+ const renderedToolUse = orphanToolUse2 ? this.getMatchingAmbiguousRenderedToolUse(toolUseId, orphanToolUse2) : void 0;
114105
+ if (renderedToolUse) {
114106
+ this.renderToolResultOnly(renderedToolUse, { result, isError: isError2 }, prefix);
114107
+ return;
114108
+ }
114109
+ if (orphanToolUse2) {
114110
+ this.renderGroupedTool(orphanToolUse2, { result, isError: isError2 }, prefix);
114111
+ }
114112
+ return;
114113
+ }
113344
114114
  const pending = this.pendingToolUse.get(toolUseId);
113345
114115
  if (pending) {
113346
- this.renderGroupedTool(pending.toolUse, { result, isError: isError2 }, prefix);
114116
+ if (pending.rendered) {
114117
+ this.renderToolResultOnly(pending.toolUse, { result, isError: isError2 }, prefix);
114118
+ } else {
114119
+ this.renderGroupedTool(pending.toolUse, { result, isError: isError2 }, prefix);
114120
+ }
113347
114121
  this.pendingToolUse.delete(toolUseId);
114122
+ return;
114123
+ }
114124
+ const orphanToolUse = this.getToolUseFromResultEvent(event);
114125
+ if (orphanToolUse) {
114126
+ this.renderGroupedTool(orphanToolUse, { result, isError: isError2 }, prefix);
114127
+ }
114128
+ }
114129
+ getToolUseFromResultEvent(event) {
114130
+ const tool = event.data.tool;
114131
+ if (typeof tool !== "string" || tool.length === 0) {
114132
+ return null;
114133
+ }
114134
+ return {
114135
+ tool,
114136
+ input: recordData(event.data.input)
114137
+ };
114138
+ }
114139
+ rememberAmbiguousRenderedToolUse(toolUseId, toolUse) {
114140
+ const renderedToolUses = this.ambiguousRenderedToolUses.get(toolUseId);
114141
+ if (renderedToolUses) {
114142
+ renderedToolUses.push(toolUse);
114143
+ return;
114144
+ }
114145
+ this.ambiguousRenderedToolUses.set(toolUseId, [toolUse]);
114146
+ }
114147
+ getMatchingAmbiguousRenderedToolUse(toolUseId, toolUse) {
114148
+ const renderedToolUses = this.ambiguousRenderedToolUses.get(toolUseId);
114149
+ if (!renderedToolUses) {
114150
+ return void 0;
114151
+ }
114152
+ for (let index = renderedToolUses.length - 1; index >= 0; index -= 1) {
114153
+ const renderedToolUse = renderedToolUses[index];
114154
+ if (renderedToolUse !== void 0 && this.hasSameToolHeader(renderedToolUse, toolUse)) {
114155
+ return renderedToolUse;
114156
+ }
113348
114157
  }
114158
+ return void 0;
114159
+ }
114160
+ hasSameToolHeader(first, second) {
114161
+ return formatToolHeader(first).join("\n") === formatToolHeader(second).join("\n");
113349
114162
  }
113350
114163
  /**
113351
114164
  * Get continuation prefix (simple indent, no timestamp alignment)
@@ -113377,12 +114190,30 @@ var EventRenderer = class _EventRenderer {
113377
114190
  console.log();
113378
114191
  this.lastEventType = "tool";
113379
114192
  }
114193
+ renderToolResultOnly(toolUse, result, prefix) {
114194
+ if (this.lastEventType === "text") {
114195
+ console.log();
114196
+ }
114197
+ const verbose = this.options.verbose ?? false;
114198
+ const cont = this.getContinuationPrefix();
114199
+ const resultLines = formatToolResult(toolUse, result, verbose);
114200
+ for (let i = 0; i < resultLines.length; i++) {
114201
+ const line = resultLines[i];
114202
+ if (i === 0) {
114203
+ console.log(prefix + cont + line);
114204
+ } else {
114205
+ console.log(cont + line);
114206
+ }
114207
+ }
114208
+ console.log();
114209
+ this.lastEventType = "tool";
114210
+ }
113380
114211
  renderInit(event, prefix) {
113381
- const frameworkStr = String(event.data.framework || "claude-code");
114212
+ const frameworkStr = displayString(event.data.framework) || "claude-code";
113382
114213
  const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
113383
114214
  this.frameworkDisplayName = displayName;
113384
114215
  console.log(prefix + source_default.bold(`\u25B7 ${displayName} Started`));
113385
- console.log(` Session: ${source_default.dim(String(event.data.sessionId || ""))}`);
114216
+ console.log(` Session: ${source_default.dim(displayString(event.data.sessionId))}`);
113386
114217
  if (event.data.model) {
113387
114218
  console.log(` Model: ${source_default.dim(String(event.data.model))}`);
113388
114219
  }
@@ -113395,29 +114226,38 @@ var EventRenderer = class _EventRenderer {
113395
114226
  this.lastEventType = "init";
113396
114227
  }
113397
114228
  renderText(event, prefix) {
113398
- const text = String(event.data.text || "");
114229
+ const text = displayString(event.data.text);
113399
114230
  console.log(prefix + "\u25CF " + text);
113400
114231
  this.lastEventType = "text";
113401
114232
  }
113402
114233
  renderResult(event, prefix) {
113403
114234
  console.log();
113404
114235
  const success = Boolean(event.data.success);
114236
+ const eventFramework = displayString(event.data.framework);
114237
+ const displayName = eventFramework && isSupportedFramework(eventFramework) ? getFrameworkDisplayName(eventFramework) : eventFramework || this.frameworkDisplayName;
114238
+ this.frameworkDisplayName = displayName;
113405
114239
  if (success) {
113406
- console.log(
113407
- prefix + source_default.bold(`\u25C6 ${this.frameworkDisplayName} Completed`)
113408
- );
114240
+ console.log(prefix + source_default.bold(`\u25C6 ${displayName} Completed`));
113409
114241
  } else {
113410
- console.log(prefix + source_default.bold(`\u25C6 ${this.frameworkDisplayName} Failed`));
114242
+ console.log(prefix + source_default.bold(`\u25C6 ${displayName} Failed`));
114243
+ const result = displayString(event.data.result).trim();
114244
+ if (result.length > 0) {
114245
+ const [firstLine, ...restLines] = result.split("\n");
114246
+ console.log(` Error: ${source_default.red(firstLine)}`);
114247
+ for (const line of restLines) {
114248
+ console.log(` ${source_default.red(line)}`);
114249
+ }
114250
+ }
113411
114251
  }
113412
- const durationMs = Number(event.data.durationMs || 0);
114252
+ const durationMs = displayNonNegativeNumber(event.data.durationMs);
113413
114253
  const durationSec = (durationMs / 1e3).toFixed(1);
113414
114254
  console.log(` Duration: ${source_default.dim(durationSec + "s")}`);
113415
- const numTurns = Number(event.data.numTurns || 0);
114255
+ const numTurns = displayNonNegativeNumber(event.data.numTurns);
113416
114256
  console.log(` Turns: ${source_default.dim(String(numTurns))}`);
113417
114257
  const usage = event.data.usage;
113418
114258
  if (usage && typeof usage === "object") {
113419
- const inputTokens = Number(usage.input_tokens || 0);
113420
- const outputTokens = Number(usage.output_tokens || 0);
114259
+ const inputTokens = displayNonNegativeNumber(usage.input_tokens);
114260
+ const outputTokens = displayNonNegativeNumber(usage.output_tokens);
113421
114261
  const formatTokens = (count) => {
113422
114262
  if (count >= 1e3) {
113423
114263
  return Math.floor(count / 1e3) + "k";
@@ -113522,8 +114362,9 @@ Expected format: '{"ref": {"permissions": {"perm": "allow|deny|ask"}}}'`
113522
114362
  }
113523
114363
  return result.data;
113524
114364
  }
114365
+ var UUID_PATTERN2 = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
113525
114366
  function isUUID(str) {
113526
- return /^[0-9a-f-]{36}$/i.test(str);
114367
+ return UUID_PATTERN2.test(str);
113527
114368
  }
113528
114369
  function extractVarNames(composeContent) {
113529
114370
  const grouped = extractAndGroupVariables(composeContent);
@@ -113606,6 +114447,9 @@ var POLL_INTERVAL_MS = 1e3;
113606
114447
  var TERMINAL_DRAIN_POLL_INTERVAL_MS = 500;
113607
114448
  var TERMINAL_DRAIN_IDLE_MS = 1e3;
113608
114449
  var TERMINAL_DRAIN_MAX_MS = 3e3;
114450
+ function supportedEventFramework(framework) {
114451
+ return isSupportedFramework(framework) ? framework : void 0;
114452
+ }
113609
114453
  function isTerminalRunState(run) {
113610
114454
  return TERMINAL_RUN_STATUSES.includes(run.status);
113611
114455
  }
@@ -113707,6 +114551,7 @@ async function pollEvents(runId, options) {
113707
114551
  for (const parsed of normalizer.flush()) {
113708
114552
  renderer.render(parsed);
113709
114553
  }
114554
+ renderer.flush();
113710
114555
  };
113711
114556
  for (; ; ) {
113712
114557
  const previousSequence = nextSequence;
@@ -113720,7 +114565,7 @@ async function pollEvents(runId, options) {
113720
114565
  for (const event of response.events) {
113721
114566
  const parsedEvents = normalizer.process(
113722
114567
  event.eventData,
113723
- response.framework
114568
+ supportedEventFramework(response.framework)
113724
114569
  );
113725
114570
  for (const parsed of parsedEvents) {
113726
114571
  renderer.render(parsed);
@@ -113947,6 +114792,17 @@ function parsePositiveLogCount(value, optionName) {
113947
114792
  }
113948
114793
  return count;
113949
114794
  }
114795
+ function parseBoundedLogCount(value, optionName, min, max) {
114796
+ const trimmed = value.trim();
114797
+ if (!/^\d+$/.test(trimmed)) {
114798
+ throw new Error(`${optionName} must be between ${min} and ${max}`);
114799
+ }
114800
+ const count = Number(trimmed);
114801
+ if (!Number.isSafeInteger(count) || count < min || count > max) {
114802
+ throw new Error(`${optionName} must be between ${min} and ${max}`);
114803
+ }
114804
+ return count;
114805
+ }
113950
114806
  async function collectLogItems(options) {
113951
114807
  const collected = [];
113952
114808
  const seenCursors = /* @__PURE__ */ new Set();
@@ -113960,9 +114816,6 @@ async function collectLogItems(options) {
113960
114816
  order: options.order
113961
114817
  });
113962
114818
  collected.push(...page.items);
113963
- if (page.items.length === 0) {
113964
- break;
113965
- }
113966
114819
  if (options.targetCount !== "all" && collected.length >= options.targetCount) {
113967
114820
  break;
113968
114821
  }
@@ -113977,6 +114830,16 @@ async function collectLogItems(options) {
113977
114830
  return options.order === "desc" ? entries.reverse() : entries;
113978
114831
  }
113979
114832
 
114833
+ // src/lib/utils/search-query.ts
114834
+ init_esm_shims();
114835
+ function parseSearchQuery(value, label) {
114836
+ const trimmed = value.trim();
114837
+ if (!trimmed) {
114838
+ throw new Error(`${label} cannot be empty.`);
114839
+ }
114840
+ return trimmed;
114841
+ }
114842
+
113980
114843
  export {
113981
114844
  InvalidArgumentError,
113982
114845
  Command,
@@ -114079,7 +114942,6 @@ export {
114079
114942
  deleteWorkflowTrigger,
114080
114943
  enableWorkflowTrigger,
114081
114944
  disableWorkflowTrigger,
114082
- runWorkflowTrigger,
114083
114945
  createGoal,
114084
114946
  editGoal,
114085
114947
  getGoal,
@@ -114161,6 +115023,7 @@ export {
114161
115023
  excludeVm0Filter,
114162
115024
  listTarFiles,
114163
115025
  removeExtraFiles,
115026
+ isSupportedFramework,
114164
115027
  getInstructionsFilename,
114165
115028
  PRESENTATION_REQUIRED_RESOURCE_IDS,
114166
115029
  listImageStyles,
@@ -114177,8 +115040,8 @@ export {
114177
115040
  selectResourceCandidates,
114178
115041
  matchFirewallBaseUrl,
114179
115042
  findMatchingPermissions,
114180
- parseEvent,
114181
115043
  EventStreamNormalizer,
115044
+ formatIsoTimestamp,
114182
115045
  EventRenderer,
114183
115046
  collectKeyValue,
114184
115047
  collectVolumeVersions,
@@ -114200,7 +115063,9 @@ export {
114200
115063
  promptConfirm,
114201
115064
  promptPassword,
114202
115065
  parsePositiveLogCount,
114203
- collectLogItems
115066
+ parseBoundedLogCount,
115067
+ collectLogItems,
115068
+ parseSearchQuery
114204
115069
  };
114205
115070
  /*! Bundled license information:
114206
115071
 
@@ -114210,4 +115075,4 @@ undici/lib/web/fetch/body.js:
114210
115075
  undici/lib/web/websocket/frame.js:
114211
115076
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
114212
115077
  */
114213
- //# sourceMappingURL=chunk-O6UJMPWI.js.map
115078
+ //# sourceMappingURL=chunk-6EGWCGWC.js.map