lunel-cli 0.1.50 → 0.1.52

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.
@@ -96,8 +96,12 @@ export declare class CodexProvider implements AIProvider {
96
96
  private extractIncomingItem;
97
97
  private describeToolPart;
98
98
  private normalizeStructuredType;
99
+ private isFileChangeStructuredItem;
99
100
  private extractStructuredOutput;
100
101
  private extractDiffLikePayload;
102
+ private renderFileChangeEntriesBody;
103
+ private renderUnifiedDiffBody;
104
+ private normalizedFileChangeStatus;
101
105
  private extractToolInput;
102
106
  private describeCompletedItemOutput;
103
107
  }
package/dist/ai/codex.js CHANGED
@@ -504,7 +504,11 @@ export class CodexProvider {
504
504
  const item = this.extractIncomingItem(params);
505
505
  const normalizedType = this.normalizeStructuredType(this.readString(item.type) ?? method);
506
506
  const itemId = this.extractItemId(params) ?? this.readString(item.id) ?? normalizedType ?? "tool";
507
- const partId = `${messageId}:tool:${itemId}`;
507
+ const fileChangeLike = this.isFileChangeStructuredItem(normalizedType, item, params);
508
+ const emittedPartType = normalizedType === "plan"
509
+ ? "reasoning"
510
+ : (fileChangeLike ? "file-change" : "tool");
511
+ const partId = `${messageId}:${emittedPartType}:${itemId}`;
508
512
  const nextText = this.extractStructuredOutput(params, item, normalizedType);
509
513
  const prevOutput = this.partTextById.get(partId) ?? "";
510
514
  const output = completed
@@ -521,8 +525,8 @@ export class CodexProvider {
521
525
  id: partId,
522
526
  sessionID: session.id,
523
527
  messageID: messageId,
524
- type: normalizedType === "plan" ? "reasoning" : "tool",
525
- ...(normalizedType === "plan"
528
+ type: emittedPartType,
529
+ ...(emittedPartType === "reasoning"
526
530
  ? { text: outputValue ?? "Planning..." }
527
531
  : { name, toolName: name, input, output: outputValue, state }),
528
532
  };
@@ -814,12 +818,15 @@ export class CodexProvider {
814
818
  const output = this.decodeFileLikeItemText(itemObject);
815
819
  if (!output)
816
820
  continue;
821
+ const emittedPartType = this.isFileChangeStructuredItem(type, itemObject)
822
+ ? "file-change"
823
+ : "tool";
817
824
  messages.push({
818
825
  id: itemId,
819
826
  role: "assistant",
820
827
  parts: [{
821
- id: `${itemId}:tool`,
822
- type: "tool",
828
+ id: `${itemId}:${emittedPartType}`,
829
+ type: emittedPartType,
823
830
  name: type,
824
831
  toolName: type,
825
832
  output,
@@ -874,11 +881,16 @@ export class CodexProvider {
874
881
  return `${this.normalizedCommandPhase(status)} ${this.shortCommand(command)}`;
875
882
  }
876
883
  decodeFileLikeItemText(itemObject) {
884
+ const status = this.normalizedFileChangeStatus(itemObject, true);
885
+ const changesBody = this.renderFileChangeEntriesBody(itemObject.changes);
886
+ if (changesBody) {
887
+ return `Status: ${status}\n\n${changesBody}`;
888
+ }
889
+ const diff = this.firstString(itemObject, ["diff", "unified_diff", "unifiedDiff", "patch"]);
890
+ if (diff?.trim()) {
891
+ return this.renderUnifiedDiffBody(diff, status);
892
+ }
877
893
  const direct = this.firstString(itemObject, [
878
- "diff",
879
- "unified_diff",
880
- "unifiedDiff",
881
- "patch",
882
894
  "text",
883
895
  "message",
884
896
  "summary",
@@ -887,20 +899,10 @@ export class CodexProvider {
887
899
  "output_text",
888
900
  "outputText",
889
901
  ]);
890
- if (direct?.trim())
891
- return direct.trim();
892
- const changes = this.readArray(itemObject.changes);
893
- if (changes.length === 0)
894
- return undefined;
895
- return changes
896
- .map((change) => {
897
- const obj = this.asRecord(change);
898
- const path = this.readString(obj.path) ?? this.readString(obj.filePath) ?? this.readString(obj.file_path) ?? "file";
899
- const kind = this.readString(obj.kind) ?? "change";
900
- const diff = this.readString(obj.diff) ?? this.readString(obj.patch) ?? "";
901
- return diff ? `${kind}: ${path}\n${diff}` : `${kind}: ${path}`;
902
- })
903
- .join("\n\n");
902
+ if (direct?.trim()) {
903
+ return `Status: ${status}\n\n${direct.trim()}`;
904
+ }
905
+ return undefined;
904
906
  }
905
907
  normalizedCommandPhase(rawStatus) {
906
908
  const normalized = rawStatus.trim().toLowerCase();
@@ -969,11 +971,20 @@ export class CodexProvider {
969
971
  extractItemId(payload) {
970
972
  return (this.readString(payload.itemId)
971
973
  ?? this.readString(payload.item_id)
974
+ ?? this.readString(payload.call_id)
975
+ ?? this.readString(payload.callId)
976
+ ?? this.readString(payload.id)
972
977
  ?? this.readString(payload.messageId)
973
978
  ?? this.readString(payload.message_id)
974
979
  ?? this.readString(this.asRecord(payload.item).id)
975
980
  ?? this.readString(this.asRecord(payload.item).itemId)
981
+ ?? this.readString(this.asRecord(payload.item).call_id)
982
+ ?? this.readString(this.asRecord(payload.item).callId)
976
983
  ?? this.readString(this.asRecord(payload.item).messageId)
984
+ ?? this.readString(this.asRecord(payload.event).itemId)
985
+ ?? this.readString(this.asRecord(payload.event).item_id)
986
+ ?? this.readString(this.asRecord(payload.event).call_id)
987
+ ?? this.readString(this.asRecord(payload.event).callId)
977
988
  ?? this.readString(this.asRecord(payload.event).id)
978
989
  ?? this.readString(this.asRecord(this.asRecord(payload.event).item).id));
979
990
  }
@@ -1095,44 +1106,102 @@ export class CodexProvider {
1095
1106
  return "commandexecution";
1096
1107
  return normalized;
1097
1108
  }
1109
+ isFileChangeStructuredItem(normalizedType, item, params) {
1110
+ if (normalizedType === "filechange" || normalizedType === "diff") {
1111
+ return true;
1112
+ }
1113
+ if (normalizedType !== "toolcall") {
1114
+ return false;
1115
+ }
1116
+ const event = this.asRecord(params?.event);
1117
+ const nestedItem = this.asRecord(event.item);
1118
+ const sources = [item, params ?? {}, event, nestedItem];
1119
+ for (const source of sources) {
1120
+ if (this.firstString(source, ["diff", "unified_diff", "unifiedDiff", "patch"])) {
1121
+ return true;
1122
+ }
1123
+ if (this.readArray(source.changes).length > 0) {
1124
+ return true;
1125
+ }
1126
+ }
1127
+ const toolName = this.firstString(item, ["name", "toolName", "tool_name", "title"])?.toLowerCase() ?? "";
1128
+ return toolName.includes("patch") || toolName.includes("edit") || toolName.includes("write");
1129
+ }
1098
1130
  extractStructuredOutput(params, item, normalizedType) {
1099
1131
  if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
1100
- return this.extractDiffLikePayload(params, item) ?? this.extractTextPayload(params);
1132
+ return this.extractDiffLikePayload(params, item, normalizedType) ?? this.extractTextPayload(params);
1101
1133
  }
1102
1134
  return this.extractTextPayload(params);
1103
1135
  }
1104
- extractDiffLikePayload(params, item) {
1136
+ extractDiffLikePayload(params, item, normalizedType) {
1105
1137
  const event = this.asRecord(params.event);
1106
1138
  const nestedItem = this.asRecord(event.item);
1107
1139
  const sources = [params, item, event, nestedItem];
1140
+ const status = this.normalizedFileChangeStatus(item, false);
1141
+ const changesBody = this.renderFileChangeEntriesBody(item.changes ?? params.changes ?? event.changes ?? nestedItem.changes);
1142
+ if (changesBody) {
1143
+ return `Status: ${status}\n\n${changesBody}`;
1144
+ }
1145
+ for (const source of sources) {
1146
+ const diff = this.firstString(source, ["diff", "unified_diff", "unifiedDiff", "patch"]);
1147
+ if (diff) {
1148
+ return this.renderUnifiedDiffBody(diff, status);
1149
+ }
1150
+ }
1108
1151
  for (const source of sources) {
1109
- const direct = this.firstString(source, [
1110
- "diff",
1111
- "unified_diff",
1112
- "unifiedDiff",
1113
- "patch",
1114
- "text",
1115
- "message",
1116
- "summary",
1117
- "output",
1118
- "output_text",
1119
- "outputText",
1120
- ]);
1121
- if (direct)
1122
- return direct;
1152
+ const direct = this.firstString(source, ["text", "message", "summary", "output", "output_text", "outputText"]);
1153
+ if (direct) {
1154
+ if (normalizedType === "toolcall" && !this.isFileChangeStructuredItem("toolcall", item, params)) {
1155
+ return direct;
1156
+ }
1157
+ return `Status: ${status}\n\n${direct}`;
1158
+ }
1123
1159
  }
1124
- const changes = this.readArray(item.changes ?? params.changes ?? event.changes ?? nestedItem.changes);
1160
+ return undefined;
1161
+ }
1162
+ renderFileChangeEntriesBody(rawChanges) {
1163
+ const changes = this.readArray(rawChanges);
1125
1164
  if (changes.length === 0)
1126
1165
  return undefined;
1127
- return changes
1166
+ const rendered = changes
1128
1167
  .map((change) => {
1129
1168
  const obj = this.asRecord(change);
1130
- const path = this.readString(obj.path) ?? this.readString(obj.filePath) ?? this.readString(obj.file_path) ?? "file";
1131
- const kind = this.readString(obj.kind) ?? "change";
1169
+ const path = this.firstString(obj, [
1170
+ "path",
1171
+ "file",
1172
+ "file_path",
1173
+ "filePath",
1174
+ "relative_path",
1175
+ "relativePath",
1176
+ "new_path",
1177
+ "newPath",
1178
+ "to",
1179
+ "target",
1180
+ "name",
1181
+ "old_path",
1182
+ "oldPath",
1183
+ "from",
1184
+ ]) ?? "file";
1185
+ const kind = this.firstString(obj, ["kind", "type", "action", "status"]) ?? "change";
1132
1186
  const diff = this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
1133
- return diff ? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\`` : `Path: ${path}\nKind: ${kind}`;
1187
+ return diff
1188
+ ? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\``
1189
+ : `Path: ${path}\nKind: ${kind}`;
1134
1190
  })
1135
- .join("\n\n---\n\n");
1191
+ .filter(Boolean);
1192
+ return rendered.length > 0 ? rendered.join("\n\n---\n\n") : undefined;
1193
+ }
1194
+ renderUnifiedDiffBody(diff, status) {
1195
+ return `Status: ${status}\n\n\`\`\`diff\n${diff.trim()}\n\`\`\``;
1196
+ }
1197
+ normalizedFileChangeStatus(itemObject, isCompleted) {
1198
+ const status = this.readString(itemObject.status)
1199
+ ?? this.readString(this.asRecord(itemObject.status).type)
1200
+ ?? this.readString(itemObject.state)
1201
+ ?? this.readString(this.asRecord(itemObject.state).type);
1202
+ if (status)
1203
+ return status;
1204
+ return isCompleted ? "completed" : "inProgress";
1136
1205
  }
1137
1206
  extractToolInput(item, params) {
1138
1207
  return item.input ?? item.command ?? item.path ?? item.args ?? params.command ?? params.path ?? undefined;
@@ -1145,7 +1214,7 @@ export class CodexProvider {
1145
1214
  return this.decodePlanItemText(item);
1146
1215
  }
1147
1216
  if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
1148
- return this.extractDiffLikePayload(params, item) ?? this.decodeFileLikeItemText(item);
1217
+ return this.extractDiffLikePayload(params, item, normalizedType) ?? this.decodeFileLikeItemText(item);
1149
1218
  }
1150
1219
  if (normalizedType === "enteredreviewmode") {
1151
1220
  return `Reviewing ${this.readString(item.review) ?? "changes"}...`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lunel-cli",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "author": [
5
5
  {
6
6
  "name": "Soham Bharambe",