lunel-cli 0.1.51 → 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();
@@ -1104,52 +1106,103 @@ export class CodexProvider {
1104
1106
  return "commandexecution";
1105
1107
  return normalized;
1106
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
+ }
1107
1130
  extractStructuredOutput(params, item, normalizedType) {
1108
1131
  if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
1109
- return this.extractDiffLikePayload(params, item) ?? this.extractTextPayload(params);
1132
+ return this.extractDiffLikePayload(params, item, normalizedType) ?? this.extractTextPayload(params);
1110
1133
  }
1111
1134
  return this.extractTextPayload(params);
1112
1135
  }
1113
- extractDiffLikePayload(params, item) {
1136
+ extractDiffLikePayload(params, item, normalizedType) {
1114
1137
  const event = this.asRecord(params.event);
1115
1138
  const nestedItem = this.asRecord(event.item);
1116
1139
  const sources = [params, item, event, nestedItem];
1117
- for (const source of sources) {
1118
- const direct = this.firstString(source, [
1119
- "diff",
1120
- "unified_diff",
1121
- "unifiedDiff",
1122
- "patch",
1123
- ]);
1124
- if (direct)
1125
- return direct;
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}`;
1126
1144
  }
1127
- const changes = this.readArray(item.changes ?? params.changes ?? event.changes ?? nestedItem.changes);
1128
- if (changes.length > 0) {
1129
- return changes
1130
- .map((change) => {
1131
- const obj = this.asRecord(change);
1132
- const path = this.readString(obj.path) ?? this.readString(obj.filePath) ?? this.readString(obj.file_path) ?? "file";
1133
- const kind = this.readString(obj.kind) ?? "change";
1134
- const diff = this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
1135
- return diff ? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\`` : `Path: ${path}\nKind: ${kind}`;
1136
- })
1137
- .join("\n\n---\n\n");
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
+ }
1138
1150
  }
1139
1151
  for (const source of sources) {
1140
- const direct = this.firstString(source, [
1141
- "text",
1142
- "message",
1143
- "summary",
1144
- "output",
1145
- "output_text",
1146
- "outputText",
1147
- ]);
1148
- if (direct)
1149
- 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
+ }
1150
1159
  }
1151
1160
  return undefined;
1152
1161
  }
1162
+ renderFileChangeEntriesBody(rawChanges) {
1163
+ const changes = this.readArray(rawChanges);
1164
+ if (changes.length === 0)
1165
+ return undefined;
1166
+ const rendered = changes
1167
+ .map((change) => {
1168
+ const obj = this.asRecord(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";
1186
+ const diff = this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
1187
+ return diff
1188
+ ? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\``
1189
+ : `Path: ${path}\nKind: ${kind}`;
1190
+ })
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";
1205
+ }
1153
1206
  extractToolInput(item, params) {
1154
1207
  return item.input ?? item.command ?? item.path ?? item.args ?? params.command ?? params.path ?? undefined;
1155
1208
  }
@@ -1161,7 +1214,7 @@ export class CodexProvider {
1161
1214
  return this.decodePlanItemText(item);
1162
1215
  }
1163
1216
  if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
1164
- return this.extractDiffLikePayload(params, item) ?? this.decodeFileLikeItemText(item);
1217
+ return this.extractDiffLikePayload(params, item, normalizedType) ?? this.decodeFileLikeItemText(item);
1165
1218
  }
1166
1219
  if (normalizedType === "enteredreviewmode") {
1167
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.51",
3
+ "version": "0.1.52",
4
4
  "author": [
5
5
  {
6
6
  "name": "Soham Bharambe",