oh-my-opencode 4.17.0 → 4.17.1

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.
Files changed (117) hide show
  1. package/.agents/command/publish.md +31 -58
  2. package/.agents/skills/pre-publish-review/SKILL.md +1 -1
  3. package/.agents/skills/publish/SKILL.md +32 -59
  4. package/.opencode/command/publish.md +31 -58
  5. package/.opencode/skills/pre-publish-review/SKILL.md +1 -1
  6. package/dist/cli/index.js +30 -27
  7. package/dist/cli-node/index.js +30 -27
  8. package/dist/index.js +202 -254
  9. package/dist/skills/review-work/SKILL.md +10 -2
  10. package/dist/skills/start-work/SKILL.md +1 -1
  11. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +2 -2
  12. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  13. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +11 -11
  14. package/dist/skills/ulw-plan/SKILL.md +2 -1
  15. package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
  16. package/dist/skills/ulw-plan/references/intent-unclear.md +4 -4
  17. package/dist/skills/visual-qa/SKILL.md +9 -5
  18. package/dist/tui.js +8 -3
  19. package/package.json +13 -13
  20. package/packages/lsp-daemon/dist/cli.js +7 -13
  21. package/packages/lsp-daemon/dist/daemon-client.js +3 -5
  22. package/packages/lsp-daemon/dist/index.js +12 -18
  23. package/packages/lsp-daemon/dist/request-routing.js +6 -8
  24. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  25. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +398 -400
  26. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  27. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  29. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  30. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  32. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  34. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +14 -14
  36. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  37. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +2 -2
  39. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +2 -2
  40. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  41. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  43. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  44. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +2 -2
  45. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  46. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  47. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +33 -16
  48. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +2 -1
  49. package/packages/omo-codex/plugin/components/teammode/test/v2-spawn-schema.test.ts +69 -0
  50. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  51. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  52. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +3 -3
  53. package/packages/omo-codex/plugin/components/ultrawork/directive.md +29 -17
  54. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  55. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  56. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +29 -17
  57. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +2 -1
  58. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
  59. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +4 -4
  60. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +9 -6
  61. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +29 -17
  62. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  63. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  64. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
  65. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -2
  66. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  67. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  68. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  69. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  70. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  71. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  72. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  73. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  74. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  84. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  85. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  87. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  88. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  89. package/packages/omo-codex/plugin/package-lock.json +13 -13
  90. package/packages/omo-codex/plugin/package.json +1 -1
  91. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +10 -2
  92. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +1 -1
  93. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +33 -16
  94. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +2 -1
  95. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +2 -2
  96. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  97. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +11 -11
  98. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +29 -17
  99. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
  100. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -2
  101. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -1
  102. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
  103. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +4 -4
  104. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +9 -5
  105. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -1
  106. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +25 -0
  107. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +24 -0
  108. package/packages/omo-codex/scripts/install-dist/install-local.mjs +9 -11
  109. package/packages/shared-skills/skills/review-work/SKILL.md +10 -2
  110. package/packages/shared-skills/skills/start-work/SKILL.md +1 -1
  111. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +2 -2
  112. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  113. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +11 -11
  114. package/packages/shared-skills/skills/ulw-plan/SKILL.md +2 -1
  115. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
  116. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +4 -4
  117. package/packages/shared-skills/skills/visual-qa/SKILL.md +9 -5
@@ -875,6 +875,329 @@ import { basename as basename3, join as join10 } from "node:path";
875
875
  import { lstat, readFile as readFile4, readdir, writeFile as writeFile3 } from "node:fs/promises";
876
876
  import { join as join8 } from "node:path";
877
877
 
878
+ // ../src/install/toml-section-editor.ts
879
+ function findTomlSection(config, header) {
880
+ const headerLine = `[${header}]`;
881
+ const targetHeaderPath = parseTomlDottedKey(header);
882
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
883
+ let offset = 0;
884
+ let start = -1;
885
+ for (const line of lines) {
886
+ if (line.length === 0)
887
+ break;
888
+ const trimmed = line.trim();
889
+ if (start === -1) {
890
+ if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
891
+ start = offset;
892
+ } else if (isTomlTableHeaderLine(line)) {
893
+ return { start, end: offset, text: config.slice(start, offset) };
894
+ }
895
+ offset += line.length;
896
+ }
897
+ if (start === -1)
898
+ return null;
899
+ return { start, end: config.length, text: config.slice(start) };
900
+ }
901
+ function replaceOrInsertSetting(config, section, key, value) {
902
+ const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
903
+ const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting(section.text, key, value);
904
+ return config.slice(0, section.start) + replacement + config.slice(section.end);
905
+ }
906
+ function removeSetting(config, section, key) {
907
+ const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*(?:\\n|$)`, "m");
908
+ const replacement = section.text.replace(linePattern, "");
909
+ return config.slice(0, section.start) + replacement + config.slice(section.end);
910
+ }
911
+ function replaceOrInsertRootSetting(config, key, value) {
912
+ const sectionStart = findFirstTableStart(config);
913
+ const root = config.slice(0, sectionStart);
914
+ const suffix = config.slice(sectionStart);
915
+ const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
916
+ const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
917
+ ` : ""}${key} = ${value}
918
+ `;
919
+ if (suffix.length === 0)
920
+ return replacement;
921
+ return `${replacement.trimEnd()}
922
+
923
+ ${suffix.trimStart()}`;
924
+ }
925
+ function appendBlock(config, block) {
926
+ const prefix = config.trimEnd();
927
+ return `${prefix}${prefix.length > 0 ? `
928
+
929
+ ` : ""}${block.trimEnd()}
930
+ `;
931
+ }
932
+ function findFirstTableStart(config) {
933
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
934
+ let offset = 0;
935
+ for (const line of lines) {
936
+ if (line.length === 0)
937
+ break;
938
+ if (isTomlTableHeaderLine(line))
939
+ return offset;
940
+ offset += line.length;
941
+ }
942
+ return config.length;
943
+ }
944
+ function insertSetting(sectionText, key, value) {
945
+ const lines = sectionText.split(`
946
+ `);
947
+ lines.splice(1, 0, `${key} = ${value}`);
948
+ return lines.join(`
949
+ `);
950
+ }
951
+ function escapeRegExp(value) {
952
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
953
+ }
954
+ function tomlTableHeaderMatches(line, headerLine, targetHeaderPath) {
955
+ const normalizedLine = stripUnquotedInlineComment(line).trim();
956
+ if (normalizedLine === headerLine)
957
+ return true;
958
+ if (!targetHeaderPath)
959
+ return false;
960
+ const candidateHeaderPath = parseTomlTableHeader(normalizedLine);
961
+ if (!candidateHeaderPath || candidateHeaderPath.length !== targetHeaderPath.length)
962
+ return false;
963
+ return candidateHeaderPath.every((part, index) => part === targetHeaderPath[index]);
964
+ }
965
+ function parseTomlTableHeader(line) {
966
+ const normalizedLine = stripUnquotedInlineComment(line).trim();
967
+ if (!normalizedLine.startsWith("[") || !normalizedLine.endsWith("]") || normalizedLine.startsWith("[["))
968
+ return null;
969
+ return parseTomlDottedKey(normalizedLine.slice(1, -1).trim());
970
+ }
971
+ function isTomlTableHeaderLine(line) {
972
+ const normalizedLine = stripUnquotedInlineComment(line).trim();
973
+ return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
974
+ }
975
+ function stripUnquotedInlineComment(line) {
976
+ let quote = null;
977
+ let index = 0;
978
+ while (index < line.length) {
979
+ const char = line[index];
980
+ if (quote === '"') {
981
+ if (char === "\\") {
982
+ index += 2;
983
+ continue;
984
+ }
985
+ if (char === '"')
986
+ quote = null;
987
+ index += 1;
988
+ continue;
989
+ }
990
+ if (quote === "'") {
991
+ if (char === "'")
992
+ quote = null;
993
+ index += 1;
994
+ continue;
995
+ }
996
+ if (char === '"' || char === "'") {
997
+ quote = char;
998
+ index += 1;
999
+ continue;
1000
+ }
1001
+ if (char === "#")
1002
+ return line.slice(0, index);
1003
+ index += 1;
1004
+ }
1005
+ return line;
1006
+ }
1007
+ function parseTomlDottedKey(input) {
1008
+ const parts = [];
1009
+ let index = 0;
1010
+ while (index < input.length) {
1011
+ index = skipWhitespace(input, index);
1012
+ const parsedKey = parseTomlKeyPart(input, index);
1013
+ if (!parsedKey)
1014
+ return null;
1015
+ parts.push(parsedKey.value);
1016
+ index = skipWhitespace(input, parsedKey.nextIndex);
1017
+ if (index === input.length)
1018
+ return parts;
1019
+ if (input[index] !== ".")
1020
+ return null;
1021
+ index += 1;
1022
+ }
1023
+ return parts.length > 0 ? parts : null;
1024
+ }
1025
+ function parseTomlKeyPart(input, startIndex) {
1026
+ const quote = input[startIndex];
1027
+ if (quote === "'")
1028
+ return parseLiteralTomlString(input, startIndex);
1029
+ if (quote === '"')
1030
+ return parseBasicTomlString(input, startIndex);
1031
+ return parseBareTomlKey(input, startIndex);
1032
+ }
1033
+ function parseLiteralTomlString(input, startIndex) {
1034
+ let index = startIndex + 1;
1035
+ let value = "";
1036
+ while (index < input.length) {
1037
+ const char = input[index];
1038
+ if (char === "'")
1039
+ return { value, nextIndex: index + 1 };
1040
+ value += char;
1041
+ index += 1;
1042
+ }
1043
+ return null;
1044
+ }
1045
+ function parseBasicTomlString(input, startIndex) {
1046
+ let index = startIndex + 1;
1047
+ let value = "";
1048
+ while (index < input.length) {
1049
+ const char = input[index];
1050
+ if (char === '"')
1051
+ return { value, nextIndex: index + 1 };
1052
+ if (char !== "\\") {
1053
+ value += char;
1054
+ index += 1;
1055
+ continue;
1056
+ }
1057
+ const escaped = parseBasicTomlEscape(input, index);
1058
+ if (!escaped)
1059
+ return null;
1060
+ value += escaped.value;
1061
+ index = escaped.nextIndex;
1062
+ }
1063
+ return null;
1064
+ }
1065
+ function parseBasicTomlEscape(input, backslashIndex) {
1066
+ const escape = input[backslashIndex + 1];
1067
+ if (escape === undefined)
1068
+ return null;
1069
+ if (escape === "b")
1070
+ return { value: "\b", nextIndex: backslashIndex + 2 };
1071
+ if (escape === "t")
1072
+ return { value: "\t", nextIndex: backslashIndex + 2 };
1073
+ if (escape === "n")
1074
+ return { value: `
1075
+ `, nextIndex: backslashIndex + 2 };
1076
+ if (escape === "f")
1077
+ return { value: "\f", nextIndex: backslashIndex + 2 };
1078
+ if (escape === "r")
1079
+ return { value: "\r", nextIndex: backslashIndex + 2 };
1080
+ if (escape === '"')
1081
+ return { value: '"', nextIndex: backslashIndex + 2 };
1082
+ if (escape === "\\")
1083
+ return { value: "\\", nextIndex: backslashIndex + 2 };
1084
+ if (escape === "u")
1085
+ return parseUnicodeEscape(input, backslashIndex + 2, 4);
1086
+ if (escape === "U")
1087
+ return parseUnicodeEscape(input, backslashIndex + 2, 8);
1088
+ return null;
1089
+ }
1090
+ function parseUnicodeEscape(input, digitsStart, digitCount) {
1091
+ const digits = input.slice(digitsStart, digitsStart + digitCount);
1092
+ if (digits.length !== digitCount || !/^[0-9A-Fa-f]+$/.test(digits))
1093
+ return null;
1094
+ const codePoint = Number.parseInt(digits, 16);
1095
+ if (codePoint > 1114111)
1096
+ return null;
1097
+ return { value: String.fromCodePoint(codePoint), nextIndex: digitsStart + digitCount };
1098
+ }
1099
+ function parseBareTomlKey(input, startIndex) {
1100
+ let index = startIndex;
1101
+ while (index < input.length && /[A-Za-z0-9_-]/.test(input[index]))
1102
+ index += 1;
1103
+ if (index === startIndex)
1104
+ return null;
1105
+ return { value: input.slice(startIndex, index), nextIndex: index };
1106
+ }
1107
+ function skipWhitespace(input, startIndex) {
1108
+ let index = startIndex;
1109
+ while (index < input.length && /\s/.test(input[index]))
1110
+ index += 1;
1111
+ return index;
1112
+ }
1113
+
1114
+ // ../src/install/codex-config-toml-sections.ts
1115
+ function removeTomlSections(config, shouldRemove) {
1116
+ return splitTomlSections(config).filter((section) => section.header === null || !shouldRemove(section.header, section)).map((section) => section.text).join("").replace(/\n{3,}/g, `
1117
+
1118
+ `);
1119
+ }
1120
+ function splitTomlSections(config) {
1121
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
1122
+ const sections = [];
1123
+ let current = { header: null, text: "" };
1124
+ for (const line of lines) {
1125
+ if (line.length === 0)
1126
+ break;
1127
+ const header = parseTomlHeader2(line);
1128
+ if (header !== null) {
1129
+ if (current.text.length > 0)
1130
+ sections.push(current);
1131
+ current = { header, text: line };
1132
+ } else {
1133
+ current = { ...current, text: current.text + line };
1134
+ }
1135
+ }
1136
+ if (current.text.length > 0)
1137
+ sections.push(current);
1138
+ return sections;
1139
+ }
1140
+ function parsePluginHeaderKey(header) {
1141
+ const path = parseTomlDottedKey(header);
1142
+ return path?.[0] === "plugins" ? path[1] ?? null : null;
1143
+ }
1144
+ function parseAgentHeaderName(header) {
1145
+ const path = parseTomlDottedKey(header);
1146
+ return path?.[0] === "agents" ? path[1] ?? null : null;
1147
+ }
1148
+ function parseJsonString(value) {
1149
+ try {
1150
+ const parsed = JSON.parse(value);
1151
+ return typeof parsed === "string" ? parsed : null;
1152
+ } catch {
1153
+ return null;
1154
+ }
1155
+ }
1156
+ function parseHookStateHeaderKey(header) {
1157
+ const path = parseTomlDottedKey(header);
1158
+ if (path?.[0] !== "hooks" || path[1] !== "state")
1159
+ return null;
1160
+ return path[2] ?? null;
1161
+ }
1162
+ function parseTomlHeader2(line) {
1163
+ const trimmed = stripTomlLineComment(line).trim();
1164
+ if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[["))
1165
+ return null;
1166
+ return trimmed.slice(1, -1);
1167
+ }
1168
+ function stripTomlLineComment(line) {
1169
+ let quote = null;
1170
+ let index = 0;
1171
+ while (index < line.length) {
1172
+ const char = line[index];
1173
+ if (quote === '"') {
1174
+ if (char === "\\") {
1175
+ index += 2;
1176
+ continue;
1177
+ }
1178
+ if (char === '"')
1179
+ quote = null;
1180
+ index += 1;
1181
+ continue;
1182
+ }
1183
+ if (quote === "'") {
1184
+ if (char === "'")
1185
+ quote = null;
1186
+ index += 1;
1187
+ continue;
1188
+ }
1189
+ if (char === '"' || char === "'") {
1190
+ quote = char;
1191
+ index += 1;
1192
+ continue;
1193
+ }
1194
+ if (char === "#")
1195
+ return line.slice(0, index);
1196
+ index += 1;
1197
+ }
1198
+ return line;
1199
+ }
1200
+
878
1201
  // ../src/install/managed-agent-reasoning-defaults.ts
879
1202
  var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
880
1203
  [
@@ -1111,16 +1434,6 @@ function isSectionHeader(line) {
1111
1434
  function agentNameFromToml(fileName) {
1112
1435
  return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
1113
1436
  }
1114
- function parseJsonString(value) {
1115
- try {
1116
- const parsed = JSON.parse(value);
1117
- return typeof parsed === "string" ? parsed : null;
1118
- } catch (error) {
1119
- if (error instanceof Error)
1120
- return null;
1121
- return null;
1122
- }
1123
- }
1124
1437
  async function exists(path) {
1125
1438
  try {
1126
1439
  await lstat(path);
@@ -1685,414 +1998,99 @@ async function appendPackageBinLinks(packageJsonPath, packageRoot, root, links)
1685
1998
  if (!isPlainRecord(packageBin))
1686
1999
  return;
1687
2000
  for (const [name, target] of Object.entries(packageBin)) {
1688
- if (typeof target !== "string")
1689
- continue;
1690
- const commandName = assertSafeCommandName(name);
1691
- if (isReservedNestedBinName(commandName, packageRoot, root))
1692
- continue;
1693
- links.push({ name: commandName, target: resolvePackageBinTarget(packageRoot, target) });
1694
- }
1695
- }
1696
- function assertSafeCommandName(name) {
1697
- if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\") || name.includes("\x00")) {
1698
- throw new Error(`Invalid package bin command name: ${name}`);
1699
- }
1700
- return name;
1701
- }
1702
- function isReservedNestedBinName(name, packageRoot, root) {
1703
- return packageRoot !== root && RESERVED_NESTED_BIN_NAMES.has(name);
1704
- }
1705
- function resolvePackageBinTarget(packageRoot, target) {
1706
- if (target.includes("\x00"))
1707
- throw new Error("Package bin target must stay inside package root");
1708
- const root = resolve4(packageRoot);
1709
- const resolvedTarget = resolve4(root, target);
1710
- const relativeTarget = relative2(root, resolvedTarget);
1711
- if (relativeTarget === "" || relativeTarget !== ".." && !relativeTarget.startsWith(`..${sep}`) && !isAbsolute3(relativeTarget)) {
1712
- return resolvedTarget;
1713
- }
1714
- throw new Error("Package bin target must stay inside package root");
1715
- }
1716
- async function replaceSymlink(linkPath, targetPath) {
1717
- if (await existingNonSymlink(linkPath))
1718
- throw new Error(`${linkPath} already exists and is not a symlink`);
1719
- await rm9(linkPath, { force: true });
1720
- await symlink(targetPath, linkPath);
1721
- }
1722
- async function replaceCommandShim(linkPath, targetPath) {
1723
- if (await existingNonShim(linkPath))
1724
- throw new Error(`${linkPath} already exists and is not a command shim`);
1725
- await writeFile5(linkPath, windowsCommandShim(targetPath));
1726
- }
1727
- async function replaceRuntimeWrapper(linkPath, content) {
1728
- if (await existingNonRuntimeWrapper(linkPath))
1729
- throw new Error(`${linkPath} already exists and is not a generated OMO runtime wrapper`);
1730
- await rm9(linkPath, { force: true });
1731
- await writeFile5(linkPath, content);
1732
- }
1733
- async function existingNonRuntimeWrapper(path) {
1734
- try {
1735
- const stat5 = await lstat7(path);
1736
- if (stat5.isSymbolicLink())
1737
- return false;
1738
- if (!stat5.isFile())
1739
- return true;
1740
- const content = await readFile8(path, "utf8");
1741
- return !content.includes(RUNTIME_WRAPPER_MARKER);
1742
- } catch (error) {
1743
- if (isNodeErrorWithCode(error) && error.code === "ENOENT")
1744
- return false;
1745
- throw error;
1746
- }
1747
- }
1748
- async function existingNonShim(path) {
1749
- try {
1750
- const stat5 = await lstat7(path);
1751
- if (!stat5.isFile())
1752
- return true;
1753
- const content = await readFile8(path, "utf8");
1754
- if (content.includes(COMMAND_SHIM_MARKER))
1755
- return false;
1756
- throw new Error(`${path} already exists and is not a generated command shim`);
1757
- } catch (error) {
1758
- if (isNodeErrorWithCode(error) && error.code === "ENOENT")
1759
- return false;
1760
- throw error;
1761
- }
1762
- }
1763
- async function existingNonSymlink(path) {
1764
- try {
1765
- const stat5 = await lstat7(path);
1766
- if (!stat5.isSymbolicLink())
1767
- return true;
1768
- await readlink3(path);
1769
- return false;
1770
- } catch (error) {
1771
- if (isNodeErrorWithCode(error) && error.code === "ENOENT")
1772
- return false;
1773
- throw error;
1774
- }
1775
- }
1776
-
1777
- // ../src/install/codex-config-toml.ts
1778
- import { mkdir as mkdir6, readFile as readFile10 } from "node:fs/promises";
1779
- import { dirname as dirname8 } from "node:path";
1780
-
1781
- // ../src/install/toml-section-editor.ts
1782
- function findTomlSection(config, header) {
1783
- const headerLine = `[${header}]`;
1784
- const targetHeaderPath = parseTomlDottedKey(header);
1785
- const lines = config.match(/[^\n]*\n?|$/g) ?? [];
1786
- let offset = 0;
1787
- let start = -1;
1788
- for (const line of lines) {
1789
- if (line.length === 0)
1790
- break;
1791
- const trimmed = line.trim();
1792
- if (start === -1) {
1793
- if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
1794
- start = offset;
1795
- } else if (isTomlTableHeaderLine(line)) {
1796
- return { start, end: offset, text: config.slice(start, offset) };
1797
- }
1798
- offset += line.length;
1799
- }
1800
- if (start === -1)
1801
- return null;
1802
- return { start, end: config.length, text: config.slice(start) };
1803
- }
1804
- function replaceOrInsertSetting(config, section, key, value) {
1805
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
1806
- const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting(section.text, key, value);
1807
- return config.slice(0, section.start) + replacement + config.slice(section.end);
1808
- }
1809
- function removeSetting(config, section, key) {
1810
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*(?:\\n|$)`, "m");
1811
- const replacement = section.text.replace(linePattern, "");
1812
- return config.slice(0, section.start) + replacement + config.slice(section.end);
1813
- }
1814
- function replaceOrInsertRootSetting(config, key, value) {
1815
- const sectionStart = findFirstTableStart(config);
1816
- const root = config.slice(0, sectionStart);
1817
- const suffix = config.slice(sectionStart);
1818
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
1819
- const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
1820
- ` : ""}${key} = ${value}
1821
- `;
1822
- if (suffix.length === 0)
1823
- return replacement;
1824
- return `${replacement.trimEnd()}
1825
-
1826
- ${suffix.trimStart()}`;
1827
- }
1828
- function appendBlock(config, block) {
1829
- const prefix = config.trimEnd();
1830
- return `${prefix}${prefix.length > 0 ? `
1831
-
1832
- ` : ""}${block.trimEnd()}
1833
- `;
1834
- }
1835
- function findFirstTableStart(config) {
1836
- const lines = config.match(/[^\n]*\n?|$/g) ?? [];
1837
- let offset = 0;
1838
- for (const line of lines) {
1839
- if (line.length === 0)
1840
- break;
1841
- if (isTomlTableHeaderLine(line))
1842
- return offset;
1843
- offset += line.length;
1844
- }
1845
- return config.length;
1846
- }
1847
- function insertSetting(sectionText, key, value) {
1848
- const lines = sectionText.split(`
1849
- `);
1850
- lines.splice(1, 0, `${key} = ${value}`);
1851
- return lines.join(`
1852
- `);
1853
- }
1854
- function escapeRegExp(value) {
1855
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1856
- }
1857
- function tomlTableHeaderMatches(line, headerLine, targetHeaderPath) {
1858
- const normalizedLine = stripUnquotedInlineComment(line).trim();
1859
- if (normalizedLine === headerLine)
1860
- return true;
1861
- if (!targetHeaderPath)
1862
- return false;
1863
- const candidateHeaderPath = parseTomlTableHeader(normalizedLine);
1864
- if (!candidateHeaderPath || candidateHeaderPath.length !== targetHeaderPath.length)
1865
- return false;
1866
- return candidateHeaderPath.every((part, index) => part === targetHeaderPath[index]);
1867
- }
1868
- function parseTomlTableHeader(line) {
1869
- const normalizedLine = stripUnquotedInlineComment(line).trim();
1870
- if (!normalizedLine.startsWith("[") || !normalizedLine.endsWith("]") || normalizedLine.startsWith("[["))
1871
- return null;
1872
- return parseTomlDottedKey(normalizedLine.slice(1, -1).trim());
1873
- }
1874
- function isTomlTableHeaderLine(line) {
1875
- const normalizedLine = stripUnquotedInlineComment(line).trim();
1876
- return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
1877
- }
1878
- function stripUnquotedInlineComment(line) {
1879
- let quote = null;
1880
- let index = 0;
1881
- while (index < line.length) {
1882
- const char = line[index];
1883
- if (quote === '"') {
1884
- if (char === "\\") {
1885
- index += 2;
1886
- continue;
1887
- }
1888
- if (char === '"')
1889
- quote = null;
1890
- index += 1;
1891
- continue;
1892
- }
1893
- if (quote === "'") {
1894
- if (char === "'")
1895
- quote = null;
1896
- index += 1;
2001
+ if (typeof target !== "string")
1897
2002
  continue;
1898
- }
1899
- if (char === '"' || char === "'") {
1900
- quote = char;
1901
- index += 1;
2003
+ const commandName = assertSafeCommandName(name);
2004
+ if (isReservedNestedBinName(commandName, packageRoot, root))
1902
2005
  continue;
1903
- }
1904
- if (char === "#")
1905
- return line.slice(0, index);
1906
- index += 1;
2006
+ links.push({ name: commandName, target: resolvePackageBinTarget(packageRoot, target) });
1907
2007
  }
1908
- return line;
1909
2008
  }
1910
- function parseTomlDottedKey(input) {
1911
- const parts = [];
1912
- let index = 0;
1913
- while (index < input.length) {
1914
- index = skipWhitespace(input, index);
1915
- const parsedKey = parseTomlKeyPart(input, index);
1916
- if (!parsedKey)
1917
- return null;
1918
- parts.push(parsedKey.value);
1919
- index = skipWhitespace(input, parsedKey.nextIndex);
1920
- if (index === input.length)
1921
- return parts;
1922
- if (input[index] !== ".")
1923
- return null;
1924
- index += 1;
2009
+ function assertSafeCommandName(name) {
2010
+ if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\") || name.includes("\x00")) {
2011
+ throw new Error(`Invalid package bin command name: ${name}`);
1925
2012
  }
1926
- return parts.length > 0 ? parts : null;
1927
- }
1928
- function parseTomlKeyPart(input, startIndex) {
1929
- const quote = input[startIndex];
1930
- if (quote === "'")
1931
- return parseLiteralTomlString(input, startIndex);
1932
- if (quote === '"')
1933
- return parseBasicTomlString(input, startIndex);
1934
- return parseBareTomlKey(input, startIndex);
2013
+ return name;
1935
2014
  }
1936
- function parseLiteralTomlString(input, startIndex) {
1937
- let index = startIndex + 1;
1938
- let value = "";
1939
- while (index < input.length) {
1940
- const char = input[index];
1941
- if (char === "'")
1942
- return { value, nextIndex: index + 1 };
1943
- value += char;
1944
- index += 1;
1945
- }
1946
- return null;
2015
+ function isReservedNestedBinName(name, packageRoot, root) {
2016
+ return packageRoot !== root && RESERVED_NESTED_BIN_NAMES.has(name);
1947
2017
  }
1948
- function parseBasicTomlString(input, startIndex) {
1949
- let index = startIndex + 1;
1950
- let value = "";
1951
- while (index < input.length) {
1952
- const char = input[index];
1953
- if (char === '"')
1954
- return { value, nextIndex: index + 1 };
1955
- if (char !== "\\") {
1956
- value += char;
1957
- index += 1;
1958
- continue;
1959
- }
1960
- const escaped = parseBasicTomlEscape(input, index);
1961
- if (!escaped)
1962
- return null;
1963
- value += escaped.value;
1964
- index = escaped.nextIndex;
2018
+ function resolvePackageBinTarget(packageRoot, target) {
2019
+ if (target.includes("\x00"))
2020
+ throw new Error("Package bin target must stay inside package root");
2021
+ const root = resolve4(packageRoot);
2022
+ const resolvedTarget = resolve4(root, target);
2023
+ const relativeTarget = relative2(root, resolvedTarget);
2024
+ if (relativeTarget === "" || relativeTarget !== ".." && !relativeTarget.startsWith(`..${sep}`) && !isAbsolute3(relativeTarget)) {
2025
+ return resolvedTarget;
1965
2026
  }
1966
- return null;
1967
- }
1968
- function parseBasicTomlEscape(input, backslashIndex) {
1969
- const escape = input[backslashIndex + 1];
1970
- if (escape === undefined)
1971
- return null;
1972
- if (escape === "b")
1973
- return { value: "\b", nextIndex: backslashIndex + 2 };
1974
- if (escape === "t")
1975
- return { value: "\t", nextIndex: backslashIndex + 2 };
1976
- if (escape === "n")
1977
- return { value: `
1978
- `, nextIndex: backslashIndex + 2 };
1979
- if (escape === "f")
1980
- return { value: "\f", nextIndex: backslashIndex + 2 };
1981
- if (escape === "r")
1982
- return { value: "\r", nextIndex: backslashIndex + 2 };
1983
- if (escape === '"')
1984
- return { value: '"', nextIndex: backslashIndex + 2 };
1985
- if (escape === "\\")
1986
- return { value: "\\", nextIndex: backslashIndex + 2 };
1987
- if (escape === "u")
1988
- return parseUnicodeEscape(input, backslashIndex + 2, 4);
1989
- if (escape === "U")
1990
- return parseUnicodeEscape(input, backslashIndex + 2, 8);
1991
- return null;
1992
- }
1993
- function parseUnicodeEscape(input, digitsStart, digitCount) {
1994
- const digits = input.slice(digitsStart, digitsStart + digitCount);
1995
- if (digits.length !== digitCount || !/^[0-9A-Fa-f]+$/.test(digits))
1996
- return null;
1997
- const codePoint = Number.parseInt(digits, 16);
1998
- if (codePoint > 1114111)
1999
- return null;
2000
- return { value: String.fromCodePoint(codePoint), nextIndex: digitsStart + digitCount };
2027
+ throw new Error("Package bin target must stay inside package root");
2001
2028
  }
2002
- function parseBareTomlKey(input, startIndex) {
2003
- let index = startIndex;
2004
- while (index < input.length && /[A-Za-z0-9_-]/.test(input[index]))
2005
- index += 1;
2006
- if (index === startIndex)
2007
- return null;
2008
- return { value: input.slice(startIndex, index), nextIndex: index };
2029
+ async function replaceSymlink(linkPath, targetPath) {
2030
+ if (await existingNonSymlink(linkPath))
2031
+ throw new Error(`${linkPath} already exists and is not a symlink`);
2032
+ await rm9(linkPath, { force: true });
2033
+ await symlink(targetPath, linkPath);
2009
2034
  }
2010
- function skipWhitespace(input, startIndex) {
2011
- let index = startIndex;
2012
- while (index < input.length && /\s/.test(input[index]))
2013
- index += 1;
2014
- return index;
2035
+ async function replaceCommandShim(linkPath, targetPath) {
2036
+ if (await existingNonShim(linkPath))
2037
+ throw new Error(`${linkPath} already exists and is not a command shim`);
2038
+ await writeFile5(linkPath, windowsCommandShim(targetPath));
2015
2039
  }
2016
-
2017
- // ../src/install/codex-config-toml-sections.ts
2018
- function removeTomlSections(config, shouldRemove) {
2019
- return splitTomlSections(config).filter((section) => section.header === null || !shouldRemove(section.header, section)).map((section) => section.text).join("").replace(/\n{3,}/g, `
2020
-
2021
- `);
2040
+ async function replaceRuntimeWrapper(linkPath, content) {
2041
+ if (await existingNonRuntimeWrapper(linkPath))
2042
+ throw new Error(`${linkPath} already exists and is not a generated OMO runtime wrapper`);
2043
+ await rm9(linkPath, { force: true });
2044
+ await writeFile5(linkPath, content);
2022
2045
  }
2023
- function splitTomlSections(config) {
2024
- const lines = config.match(/[^\n]*\n?|$/g) ?? [];
2025
- const sections = [];
2026
- let current = { header: null, text: "" };
2027
- for (const line of lines) {
2028
- if (line.length === 0)
2029
- break;
2030
- const header = parseTomlHeader2(line);
2031
- if (header !== null) {
2032
- if (current.text.length > 0)
2033
- sections.push(current);
2034
- current = { header, text: line };
2035
- } else {
2036
- current = { ...current, text: current.text + line };
2037
- }
2046
+ async function existingNonRuntimeWrapper(path) {
2047
+ try {
2048
+ const stat5 = await lstat7(path);
2049
+ if (stat5.isSymbolicLink())
2050
+ return false;
2051
+ if (!stat5.isFile())
2052
+ return true;
2053
+ const content = await readFile8(path, "utf8");
2054
+ return !content.includes(RUNTIME_WRAPPER_MARKER);
2055
+ } catch (error) {
2056
+ if (isNodeErrorWithCode(error) && error.code === "ENOENT")
2057
+ return false;
2058
+ throw error;
2038
2059
  }
2039
- if (current.text.length > 0)
2040
- sections.push(current);
2041
- return sections;
2042
- }
2043
- function parsePluginHeaderKey(header) {
2044
- const path = parseTomlDottedKey(header);
2045
- return path?.[0] === "plugins" ? path[1] ?? null : null;
2046
- }
2047
- function parseAgentHeaderName(header) {
2048
- const path = parseTomlDottedKey(header);
2049
- return path?.[0] === "agents" ? path[1] ?? null : null;
2050
- }
2051
- function parseHookStateHeaderKey(header) {
2052
- const path = parseTomlDottedKey(header);
2053
- if (path?.[0] !== "hooks" || path[1] !== "state")
2054
- return null;
2055
- return path[2] ?? null;
2056
2060
  }
2057
- function parseTomlHeader2(line) {
2058
- const trimmed = stripTomlLineComment(line).trim();
2059
- if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[["))
2060
- return null;
2061
- return trimmed.slice(1, -1);
2061
+ async function existingNonShim(path) {
2062
+ try {
2063
+ const stat5 = await lstat7(path);
2064
+ if (!stat5.isFile())
2065
+ return true;
2066
+ const content = await readFile8(path, "utf8");
2067
+ if (content.includes(COMMAND_SHIM_MARKER))
2068
+ return false;
2069
+ throw new Error(`${path} already exists and is not a generated command shim`);
2070
+ } catch (error) {
2071
+ if (isNodeErrorWithCode(error) && error.code === "ENOENT")
2072
+ return false;
2073
+ throw error;
2074
+ }
2062
2075
  }
2063
- function stripTomlLineComment(line) {
2064
- let quote = null;
2065
- let index = 0;
2066
- while (index < line.length) {
2067
- const char = line[index];
2068
- if (quote === '"') {
2069
- if (char === "\\") {
2070
- index += 2;
2071
- continue;
2072
- }
2073
- if (char === '"')
2074
- quote = null;
2075
- index += 1;
2076
- continue;
2077
- }
2078
- if (quote === "'") {
2079
- if (char === "'")
2080
- quote = null;
2081
- index += 1;
2082
- continue;
2083
- }
2084
- if (char === '"' || char === "'") {
2085
- quote = char;
2086
- index += 1;
2087
- continue;
2088
- }
2089
- if (char === "#")
2090
- return line.slice(0, index);
2091
- index += 1;
2076
+ async function existingNonSymlink(path) {
2077
+ try {
2078
+ const stat5 = await lstat7(path);
2079
+ if (!stat5.isSymbolicLink())
2080
+ return true;
2081
+ await readlink3(path);
2082
+ return false;
2083
+ } catch (error) {
2084
+ if (isNodeErrorWithCode(error) && error.code === "ENOENT")
2085
+ return false;
2086
+ throw error;
2092
2087
  }
2093
- return line;
2094
2088
  }
2095
2089
 
2090
+ // ../src/install/codex-config-toml.ts
2091
+ import { mkdir as mkdir6, readFile as readFile10 } from "node:fs/promises";
2092
+ import { dirname as dirname8 } from "node:path";
2093
+
2096
2094
  // ../src/install/codex-config-agents.ts
2097
2095
  var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE = ["codex-ultrawork-reviewer"];
2098
2096
  var CURRENT_MANAGED_CODEX_AGENT_NAMES = [