oh-my-opencode 5.1.27 → 5.1.29

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 (56) hide show
  1. package/dist/cli/index.js +501 -47
  2. package/dist/cli-node/index.js +501 -47
  3. package/dist/index.js +523 -55
  4. package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
  5. package/dist/tui.js +256 -27
  6. package/package.json +14 -14
  7. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  8. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  9. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  10. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  11. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  12. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  13. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  14. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  15. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  16. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  17. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  18. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  19. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  20. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  21. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  22. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  23. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  24. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  25. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  26. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  27. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  28. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  29. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  30. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  31. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  32. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  33. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  34. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  35. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  36. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  37. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  38. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  39. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  40. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  41. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  42. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  43. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  44. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  45. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  46. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  47. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  52. package/packages/omo-codex/plugin/package-lock.json +12 -12
  53. package/packages/omo-codex/plugin/package.json +1 -1
  54. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  55. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  56. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "oh-my-opencode",
68
- version: "5.1.27",
68
+ version: "5.1.29",
69
69
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
70
70
  main: "./dist/index.js",
71
71
  types: "dist/index.d.ts",
@@ -242,7 +242,7 @@ var init_package = __esm(() => {
242
242
  },
243
243
  devDependencies: {
244
244
  "@clack/prompts": "^1.8.1",
245
- "@code-yeongyu/senpi": "2026.10.10-9",
245
+ "@code-yeongyu/senpi": "2026.10.10-11",
246
246
  "@modelcontextprotocol/sdk": "^1.30.0",
247
247
  "@oh-my-opencode/agents-md-core": "workspace:*",
248
248
  "@oh-my-opencode/ast-grep-mcp": "workspace:*",
@@ -300,18 +300,18 @@ var init_package = __esm(() => {
300
300
  typescript: "^7.0.2"
301
301
  },
302
302
  optionalDependencies: {
303
- "oh-my-opencode-darwin-arm64": "5.1.27",
304
- "oh-my-opencode-darwin-x64": "5.1.27",
305
- "oh-my-opencode-darwin-x64-baseline": "5.1.27",
306
- "oh-my-opencode-linux-arm64": "5.1.27",
307
- "oh-my-opencode-linux-arm64-musl": "5.1.27",
308
- "oh-my-opencode-linux-x64": "5.1.27",
309
- "oh-my-opencode-linux-x64-baseline": "5.1.27",
310
- "oh-my-opencode-linux-x64-musl": "5.1.27",
311
- "oh-my-opencode-linux-x64-musl-baseline": "5.1.27",
312
- "oh-my-opencode-windows-arm64": "5.1.27",
313
- "oh-my-opencode-windows-x64": "5.1.27",
314
- "oh-my-opencode-windows-x64-baseline": "5.1.27"
303
+ "oh-my-opencode-darwin-arm64": "5.1.29",
304
+ "oh-my-opencode-darwin-x64": "5.1.29",
305
+ "oh-my-opencode-darwin-x64-baseline": "5.1.29",
306
+ "oh-my-opencode-linux-arm64": "5.1.29",
307
+ "oh-my-opencode-linux-arm64-musl": "5.1.29",
308
+ "oh-my-opencode-linux-x64": "5.1.29",
309
+ "oh-my-opencode-linux-x64-baseline": "5.1.29",
310
+ "oh-my-opencode-linux-x64-musl": "5.1.29",
311
+ "oh-my-opencode-linux-x64-musl-baseline": "5.1.29",
312
+ "oh-my-opencode-windows-arm64": "5.1.29",
313
+ "oh-my-opencode-windows-x64": "5.1.29",
314
+ "oh-my-opencode-windows-x64-baseline": "5.1.29"
315
315
  },
316
316
  overrides: {
317
317
  hono: "^4.13.8",
@@ -4852,7 +4852,7 @@ function applyEdits(text, edits) {
4852
4852
  }
4853
4853
  return text;
4854
4854
  }
4855
- var ScanError, SyntaxKind, parse2, ParseErrorCode;
4855
+ var ScanError, SyntaxKind, parse2, parseTree2, findNodeAtLocation2, ParseErrorCode;
4856
4856
  var init_main = __esm(() => {
4857
4857
  init_format();
4858
4858
  init_edit();
@@ -4887,6 +4887,8 @@ var init_main = __esm(() => {
4887
4887
  SyntaxKind[SyntaxKind["EOF"] = 17] = "EOF";
4888
4888
  })(SyntaxKind || (SyntaxKind = {}));
4889
4889
  parse2 = parse;
4890
+ parseTree2 = parseTree;
4891
+ findNodeAtLocation2 = findNodeAtLocation;
4890
4892
  (function(ParseErrorCode) {
4891
4893
  ParseErrorCode[ParseErrorCode["InvalidSymbol"] = 1] = "InvalidSymbol";
4892
4894
  ParseErrorCode[ParseErrorCode["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
@@ -7246,20 +7248,20 @@ var init_agent_model_requirements = __esm(() => {
7246
7248
  fallbackChain: [
7247
7249
  { providers: ["kimi-for-coding"], model: "kimi-for-coding-highspeed", variant: "off" },
7248
7250
  { providers: ["openai", "chatgpt-subscription"], model: "gpt-6-luna-fast", variant: "low" },
7251
+ { providers: ["anthropic", "github-copilot"], model: "claude-haiku-5-5", variant: "medium" },
7249
7252
  { providers: ["deepseek"], model: "deepseek-flash", variant: "max" },
7250
7253
  { providers: ["opencode-go", "bailian-coding-plan"], model: "qwen3.7-plus" },
7251
- { providers: ["opencode-go"], model: "minimax-m2.7" },
7252
- { providers: ["anthropic", "github-copilot"], model: "claude-haiku-4-5" }
7254
+ { providers: ["opencode-go"], model: "minimax-m2.7" }
7253
7255
  ]
7254
7256
  },
7255
7257
  explore: {
7256
7258
  fallbackChain: [
7257
7259
  { providers: ["kimi-for-coding"], model: "kimi-for-coding-highspeed", variant: "off" },
7258
7260
  { providers: ["openai", "chatgpt-subscription"], model: "gpt-6-luna-fast", variant: "low" },
7261
+ { providers: ["anthropic", "github-copilot"], model: "claude-haiku-5-5", variant: "medium" },
7259
7262
  { providers: ["deepseek"], model: "deepseek-flash", variant: "max" },
7260
7263
  { providers: ["opencode-go", "bailian-coding-plan"], model: "qwen3.7-plus" },
7261
- { providers: ["opencode-go"], model: "minimax-m2.7" },
7262
- { providers: ["anthropic", "github-copilot"], model: "claude-haiku-4-5" }
7264
+ { providers: ["opencode-go"], model: "minimax-m2.7" }
7263
7265
  ]
7264
7266
  },
7265
7267
  "multimodal-looker": {
@@ -7434,6 +7436,11 @@ var init_category_model_requirements = __esm(() => {
7434
7436
  quick: {
7435
7437
  fallbackChain: [
7436
7438
  { providers: ["openai", "chatgpt-subscription"], model: "gpt-6-luna-fast", variant: "low" },
7439
+ {
7440
+ providers: ["anthropic", "anthropic-api", "github-copilot"],
7441
+ model: "claude-haiku-5-5",
7442
+ variant: "medium"
7443
+ },
7437
7444
  { providers: ["deepseek"], model: "deepseek-flash", variant: "off" },
7438
7445
  {
7439
7446
  providers: ["qwen-token-plan", "alibaba-token-plan", "bailian-coding-plan"],
@@ -7443,11 +7450,6 @@ var init_category_model_requirements = __esm(() => {
7443
7450
  { providers: ["opencode-go"], model: "minimax-m3", variant: "max" },
7444
7451
  { providers: ["opencode-go"], model: "minimax-m2.7", variant: "max" },
7445
7452
  { providers: ["xai"], model: "grok-4.20-0309-non-reasoning" },
7446
- {
7447
- providers: ["anthropic", "anthropic-api", "github-copilot"],
7448
- model: "claude-haiku-4-5",
7449
- variant: "off"
7450
- },
7451
7453
  { providers: ["zai-coding-plan"], model: "glm-5.3-flash", variant: "low" },
7452
7454
  { providers: ["xiaomi"], model: "mimo-v2.6-flash", variant: "low" }
7453
7455
  ]
@@ -64910,6 +64912,237 @@ var init_model_capabilities_generated = __esm(() => {
64910
64912
  input: 1048576,
64911
64913
  output: 131072
64912
64914
  }
64915
+ },
64916
+ "claude-haiku-5-5": {
64917
+ id: "claude-haiku-5-5",
64918
+ family: "claude-haiku",
64919
+ reasoning: true,
64920
+ temperature: false,
64921
+ toolCall: true,
64922
+ modalities: {
64923
+ input: [
64924
+ "text",
64925
+ "image",
64926
+ "pdf"
64927
+ ],
64928
+ output: [
64929
+ "text"
64930
+ ]
64931
+ },
64932
+ limit: {
64933
+ context: 1e6,
64934
+ output: 128000
64935
+ }
64936
+ },
64937
+ "claude-haiku-5-5@default": {
64938
+ id: "claude-haiku-5-5@default",
64939
+ family: "claude-haiku",
64940
+ reasoning: true,
64941
+ temperature: false,
64942
+ toolCall: true,
64943
+ modalities: {
64944
+ input: [
64945
+ "text",
64946
+ "image",
64947
+ "pdf"
64948
+ ],
64949
+ output: [
64950
+ "text"
64951
+ ]
64952
+ },
64953
+ limit: {
64954
+ context: 1e6,
64955
+ output: 128000
64956
+ }
64957
+ },
64958
+ "au.anthropic.claude-haiku-5-5": {
64959
+ id: "au.anthropic.claude-haiku-5-5",
64960
+ family: "claude-haiku",
64961
+ reasoning: true,
64962
+ temperature: false,
64963
+ toolCall: true,
64964
+ modalities: {
64965
+ input: [
64966
+ "text",
64967
+ "image",
64968
+ "pdf"
64969
+ ],
64970
+ output: [
64971
+ "text"
64972
+ ]
64973
+ },
64974
+ limit: {
64975
+ context: 1e6,
64976
+ output: 128000
64977
+ }
64978
+ },
64979
+ "anthropic.claude-haiku-5-5": {
64980
+ id: "anthropic.claude-haiku-5-5",
64981
+ family: "claude-haiku",
64982
+ reasoning: true,
64983
+ temperature: false,
64984
+ toolCall: true,
64985
+ modalities: {
64986
+ input: [
64987
+ "text",
64988
+ "image",
64989
+ "pdf"
64990
+ ],
64991
+ output: [
64992
+ "text"
64993
+ ]
64994
+ },
64995
+ limit: {
64996
+ context: 1e6,
64997
+ output: 128000
64998
+ }
64999
+ },
65000
+ "eu.anthropic.claude-haiku-5-5": {
65001
+ id: "eu.anthropic.claude-haiku-5-5",
65002
+ family: "claude-haiku",
65003
+ reasoning: true,
65004
+ temperature: false,
65005
+ toolCall: true,
65006
+ modalities: {
65007
+ input: [
65008
+ "text",
65009
+ "image",
65010
+ "pdf"
65011
+ ],
65012
+ output: [
65013
+ "text"
65014
+ ]
65015
+ },
65016
+ limit: {
65017
+ context: 1e6,
65018
+ output: 128000
65019
+ }
65020
+ },
65021
+ "global.anthropic.claude-haiku-5-5": {
65022
+ id: "global.anthropic.claude-haiku-5-5",
65023
+ family: "claude-haiku",
65024
+ reasoning: true,
65025
+ temperature: false,
65026
+ toolCall: true,
65027
+ modalities: {
65028
+ input: [
65029
+ "text",
65030
+ "image",
65031
+ "pdf"
65032
+ ],
65033
+ output: [
65034
+ "text"
65035
+ ]
65036
+ },
65037
+ limit: {
65038
+ context: 1e6,
65039
+ output: 128000
65040
+ }
65041
+ },
65042
+ "jp.anthropic.claude-haiku-5-5": {
65043
+ id: "jp.anthropic.claude-haiku-5-5",
65044
+ family: "claude-haiku",
65045
+ reasoning: true,
65046
+ temperature: false,
65047
+ toolCall: true,
65048
+ modalities: {
65049
+ input: [
65050
+ "text",
65051
+ "image",
65052
+ "pdf"
65053
+ ],
65054
+ output: [
65055
+ "text"
65056
+ ]
65057
+ },
65058
+ limit: {
65059
+ context: 1e6,
65060
+ output: 128000
65061
+ }
65062
+ },
65063
+ "us.anthropic.claude-haiku-5-5": {
65064
+ id: "us.anthropic.claude-haiku-5-5",
65065
+ family: "claude-haiku",
65066
+ reasoning: true,
65067
+ temperature: false,
65068
+ toolCall: true,
65069
+ modalities: {
65070
+ input: [
65071
+ "text",
65072
+ "image",
65073
+ "pdf"
65074
+ ],
65075
+ output: [
65076
+ "text"
65077
+ ]
65078
+ },
65079
+ limit: {
65080
+ context: 1e6,
65081
+ output: 128000
65082
+ }
65083
+ },
65084
+ "anthropic/claude-haiku-5-5": {
65085
+ id: "anthropic/claude-haiku-5-5",
65086
+ family: "claude-haiku",
65087
+ reasoning: true,
65088
+ temperature: false,
65089
+ toolCall: true,
65090
+ modalities: {
65091
+ input: [
65092
+ "text",
65093
+ "image"
65094
+ ],
65095
+ output: [
65096
+ "text"
65097
+ ]
65098
+ },
65099
+ limit: {
65100
+ context: 1e6,
65101
+ output: 128000
65102
+ }
65103
+ },
65104
+ "claude-haiku-5.5": {
65105
+ id: "claude-haiku-5.5",
65106
+ family: "claude-haiku",
65107
+ reasoning: true,
65108
+ temperature: false,
65109
+ toolCall: true,
65110
+ modalities: {
65111
+ input: [
65112
+ "text",
65113
+ "image",
65114
+ "pdf"
65115
+ ],
65116
+ output: [
65117
+ "text"
65118
+ ]
65119
+ },
65120
+ limit: {
65121
+ context: 1e6,
65122
+ output: 128000
65123
+ }
65124
+ },
65125
+ "anthropic/claude-haiku-5.5": {
65126
+ id: "anthropic/claude-haiku-5.5",
65127
+ family: "claude-haiku",
65128
+ reasoning: true,
65129
+ temperature: false,
65130
+ toolCall: true,
65131
+ modalities: {
65132
+ input: [
65133
+ "text",
65134
+ "image",
65135
+ "pdf"
65136
+ ],
65137
+ output: [
65138
+ "text"
65139
+ ]
65140
+ },
65141
+ limit: {
65142
+ context: 1e6,
65143
+ input: 1e6,
65144
+ output: 128000
65145
+ }
64913
65146
  }
64914
65147
  }
64915
65148
  };
@@ -68052,7 +68285,7 @@ var init_claude_model_mapper = __esm(() => {
68052
68285
  CLAUDE_CODE_ALIAS_MAP = new Map([
68053
68286
  ["sonnet", `${ANTHROPIC_PREFIX}claude-sonnet-4-6`],
68054
68287
  ["opus", `${ANTHROPIC_PREFIX}claude-opus-4-8`],
68055
- ["haiku", `${ANTHROPIC_PREFIX}claude-haiku-4-5`]
68288
+ ["haiku", `${ANTHROPIC_PREFIX}claude-haiku-5-5`]
68056
68289
  ]);
68057
68290
  });
68058
68291
 
@@ -76240,6 +76473,187 @@ var init_jsonc_parse = __esm(() => {
76240
76473
  init_main();
76241
76474
  });
76242
76475
 
76476
+ // packages/omo-config-core/src/writer/surgical-edit.ts
76477
+ function applyOmoConfigEdit(content, edit) {
76478
+ const fallback = formattedModify(content, edit);
76479
+ const surgical = surgicalEditPreservingEol(content, edit);
76480
+ if (surgical === undefined)
76481
+ return fallback;
76482
+ if (parses(fallback))
76483
+ return sameData(surgical, fallback) ? surgical : fallback;
76484
+ return parses(surgical) ? surgical : fallback;
76485
+ }
76486
+ function surgicalEditPreservingEol(content, edit) {
76487
+ const crlf = content.includes(`\r
76488
+ `);
76489
+ if (crlf && /(?<!\r)\n/.test(content))
76490
+ return;
76491
+ const text = crlf ? content.replaceAll(`\r
76492
+ `, `
76493
+ `) : content;
76494
+ const edited = surgicalEdit(text, edit);
76495
+ if (edited === undefined)
76496
+ return;
76497
+ return crlf ? edited.replaceAll(`
76498
+ `, `\r
76499
+ `) : edited;
76500
+ }
76501
+ function parses(content) {
76502
+ return parseJsoncSafe3(content).errors.length === 0;
76503
+ }
76504
+ function surgicalEdit(content, edit) {
76505
+ const root = parseTree2(content);
76506
+ if (root === undefined)
76507
+ return;
76508
+ const target = findNodeAtLocation2(root, [...edit.path]);
76509
+ if (target !== undefined)
76510
+ return edit.value === undefined ? removeMember(content, target) : undefined;
76511
+ if (edit.value === undefined)
76512
+ return content;
76513
+ return insertMember(content, root, edit);
76514
+ }
76515
+ function sameData(surgical, fallback) {
76516
+ const left = parseJsoncSafe3(surgical);
76517
+ const right = parseJsoncSafe3(fallback);
76518
+ if (left.errors.length > 0 || right.errors.length > 0)
76519
+ return false;
76520
+ return JSON.stringify(left.data) === JSON.stringify(right.data);
76521
+ }
76522
+ function formattedModify(content, edit) {
76523
+ return applyEdits(content, modify(content, [...edit.path], edit.value, { formattingOptions: FORMATTING_OPTIONS }));
76524
+ }
76525
+ function lineStart(content, offset) {
76526
+ return content.lastIndexOf(`
76527
+ `, offset - 1) + 1;
76528
+ }
76529
+ function lineEnd(content, offset) {
76530
+ const end = content.indexOf(`
76531
+ `, offset);
76532
+ return end === -1 ? content.length : end;
76533
+ }
76534
+ function leadingWhitespace(content, offset) {
76535
+ const start = lineStart(content, offset);
76536
+ return /^[ \t]*/.exec(content.slice(start))?.[0] ?? "";
76537
+ }
76538
+ function onlyWhitespaceBefore(content, offset) {
76539
+ return /^[ \t]*$/.test(content.slice(lineStart(content, offset), offset));
76540
+ }
76541
+ function commaAfter(content, offset) {
76542
+ const match = /^[ \t]*,/.exec(content.slice(offset));
76543
+ return match === null ? undefined : offset + match[0].length - 1;
76544
+ }
76545
+ function lineRestIsTrivia(content, offset) {
76546
+ const rest = content.slice(offset, lineEnd(content, offset));
76547
+ return /^[ \t]*,?[ \t]*(?:\/\/.*|\/\*(?:(?!\*\/).)*\*\/[ \t]*)?$/.test(rest);
76548
+ }
76549
+ function memberNodes(objectNode) {
76550
+ return (objectNode.children ?? []).filter((child) => child.type === "property");
76551
+ }
76552
+ function fileIndentUnit(content) {
76553
+ const indents = [...content.matchAll(/\n([ \t]+)\S/g)].map((match) => match[1] ?? "");
76554
+ if (indents.some((indent) => indent.startsWith("\t")))
76555
+ return "\t";
76556
+ const widths = indents.map((indent) => indent.length).filter((width) => width > 0);
76557
+ return " ".repeat(widths.length === 0 ? 2 : Math.min(...widths));
76558
+ }
76559
+ function indentUnit(content, memberIndent, objectIndent) {
76560
+ if (memberIndent.startsWith(objectIndent) && memberIndent.length > objectIndent.length) {
76561
+ return memberIndent.slice(objectIndent.length);
76562
+ }
76563
+ return fileIndentUnit(content);
76564
+ }
76565
+ function renderMember(key, value, memberIndent, unit) {
76566
+ const rendered = JSON.stringify(value, null, unit).split(`
76567
+ `).join(`
76568
+ ${memberIndent}`);
76569
+ return `${JSON.stringify(key)}: ${rendered}`;
76570
+ }
76571
+ function nestedValue(path, value) {
76572
+ return path.reduceRight((inner, segment) => ({ [String(segment)]: inner }), value);
76573
+ }
76574
+ function insertMember(content, root, edit) {
76575
+ let depth = edit.path.length - 1;
76576
+ let parent;
76577
+ while (depth >= 0) {
76578
+ parent = depth === 0 ? root : findNodeAtLocation2(root, [...edit.path.slice(0, depth)]);
76579
+ if (parent !== undefined)
76580
+ break;
76581
+ depth -= 1;
76582
+ }
76583
+ if (parent === undefined || parent.type !== "object")
76584
+ return;
76585
+ const key = edit.path[depth];
76586
+ if (typeof key !== "string")
76587
+ return;
76588
+ const value = nestedValue(edit.path.slice(depth + 1), edit.value);
76589
+ const objectIndent = leadingWhitespace(content, parent.offset);
76590
+ const closeBrace = parent.offset + parent.length - 1;
76591
+ const members = memberNodes(parent);
76592
+ const last = members.at(-1);
76593
+ if (last === undefined) {
76594
+ if (!/^\{\s*\}$/.test(content.slice(parent.offset, closeBrace + 1)))
76595
+ return;
76596
+ const unit = fileIndentUnit(content);
76597
+ const memberIndent = `${objectIndent}${unit}`;
76598
+ const member = renderMember(key, value, memberIndent, unit);
76599
+ return `${content.slice(0, parent.offset)}{
76600
+ ${memberIndent}${member}
76601
+ ${objectIndent}}${content.slice(closeBrace + 1)}`;
76602
+ }
76603
+ if (!onlyWhitespaceBefore(content, last.offset))
76604
+ return;
76605
+ const lastEnd = last.offset + last.length;
76606
+ if (!lineRestIsTrivia(content, lastEnd))
76607
+ return;
76608
+ const insertAt = lineEnd(content, lastEnd);
76609
+ if (insertAt >= closeBrace)
76610
+ return;
76611
+ const memberIndent = leadingWhitespace(content, last.offset);
76612
+ const unit = indentUnit(content, memberIndent, objectIndent);
76613
+ const trailingComma = commaAfter(content, lastEnd);
76614
+ const member = renderMember(key, value, memberIndent, unit);
76615
+ const head = trailingComma === undefined ? `${content.slice(0, lastEnd)},${content.slice(lastEnd, insertAt)}` : content.slice(0, insertAt);
76616
+ return `${head}
76617
+ ${memberIndent}${member}${trailingComma === undefined ? "" : ","}${content.slice(insertAt)}`;
76618
+ }
76619
+ function removeMember(content, valueNode) {
76620
+ const property = valueNode.parent;
76621
+ if (property?.type !== "property" || property.parent?.type !== "object")
76622
+ return;
76623
+ if (!onlyWhitespaceBefore(content, property.offset))
76624
+ return;
76625
+ const end = property.offset + property.length;
76626
+ if (!lineRestIsTrivia(content, end))
76627
+ return;
76628
+ const members = memberNodes(property.parent);
76629
+ const index = members.indexOf(property);
76630
+ const isLast = index === members.length - 1;
76631
+ const removeFrom = lineStart(content, property.offset);
76632
+ const lineAfter = lineEnd(content, end);
76633
+ const removeTo = lineAfter < content.length ? lineAfter + 1 : lineAfter;
76634
+ const removed = `${content.slice(0, removeFrom)}${content.slice(removeTo)}`;
76635
+ if (!isLast || commaAfter(content, end) !== undefined || index === 0)
76636
+ return removed;
76637
+ const previous = members[index - 1];
76638
+ if (previous === undefined)
76639
+ return removed;
76640
+ const previousComma = commaAfter(content, previous.offset + previous.length);
76641
+ if (previousComma === undefined)
76642
+ return removed;
76643
+ return `${removed.slice(0, previousComma)}${removed.slice(previousComma + 1)}`;
76644
+ }
76645
+ var FORMATTING_OPTIONS;
76646
+ var init_surgical_edit = __esm(() => {
76647
+ init_main();
76648
+ init_jsonc_parse();
76649
+ FORMATTING_OPTIONS = {
76650
+ eol: `
76651
+ `,
76652
+ insertSpaces: true,
76653
+ tabSize: 2
76654
+ };
76655
+ });
76656
+
76243
76657
  // packages/omo-config-core/src/writer/writer.ts
76244
76658
  import { randomUUID as randomUUID2 } from "node:crypto";
76245
76659
  import { dirname as dirname5, join as join16, posix as posix3 } from "node:path";
@@ -76367,7 +76781,7 @@ function updateOmoConfig(options) {
76367
76781
  }
76368
76782
  let nextContent = content;
76369
76783
  for (const edit of options.edits) {
76370
- nextContent = applyEdits(nextContent, modify(nextContent, [...edit.path], edit.value, { formattingOptions: FORMATTING_OPTIONS }));
76784
+ nextContent = applyOmoConfigEdit(nextContent, edit);
76371
76785
  }
76372
76786
  writeAtomically(path, nextContent, fileSystem);
76373
76787
  return backupPath === undefined ? { path } : { backupPath, path };
@@ -76375,18 +76789,12 @@ function updateOmoConfig(options) {
76375
76789
  var EMPTY_OMO_CONFIG = `// OMO configuration
76376
76790
  {
76377
76791
  }
76378
- `, FORMATTING_OPTIONS;
76792
+ `;
76379
76793
  var init_writer = __esm(() => {
76380
76794
  init_jsonc_parse();
76381
- init_main();
76382
76795
  init_loader3();
76796
+ init_surgical_edit();
76383
76797
  init_types4();
76384
- FORMATTING_OPTIONS = {
76385
- eol: `
76386
- `,
76387
- insertSpaces: true,
76388
- tabSize: 2
76389
- };
76390
76798
  });
76391
76799
 
76392
76800
  // packages/omo-config-core/src/writer/index.ts
@@ -76422,6 +76830,57 @@ function moveMigrationBackup(fileSystem, sourcePath, backupPath) {
76422
76830
  }
76423
76831
  }
76424
76832
 
76833
+ // packages/omo-config-core/src/migration/diff-edits.ts
76834
+ function deepEqual(left, right) {
76835
+ if (left === right)
76836
+ return true;
76837
+ if (Array.isArray(left) || Array.isArray(right)) {
76838
+ if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length)
76839
+ return false;
76840
+ return left.every((entry, index) => deepEqual(entry, right[index]));
76841
+ }
76842
+ if (!isPlainObject5(left) || !isPlainObject5(right))
76843
+ return false;
76844
+ const leftKeys = Object.keys(left);
76845
+ if (leftKeys.length !== Object.keys(right).length)
76846
+ return false;
76847
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key]));
76848
+ }
76849
+ function withoutMarker(document) {
76850
+ const { _migrations: _marker, ...rest } = document;
76851
+ return rest;
76852
+ }
76853
+ function diffEdits(before, after, path = []) {
76854
+ const edits = [];
76855
+ for (const key of Object.keys(before)) {
76856
+ if (isUnsafeObjectKey3(key))
76857
+ continue;
76858
+ if (!Object.prototype.hasOwnProperty.call(after, key))
76859
+ edits.push({ path: [...path, key], value: undefined });
76860
+ }
76861
+ for (const [key, value] of Object.entries(after)) {
76862
+ if (isUnsafeObjectKey3(key))
76863
+ continue;
76864
+ const nextPath = [...path, key];
76865
+ if (!Object.prototype.hasOwnProperty.call(before, key)) {
76866
+ edits.push({ path: nextPath, value });
76867
+ continue;
76868
+ }
76869
+ const previous = before[key];
76870
+ if (deepEqual(previous, value))
76871
+ continue;
76872
+ if (isPlainObject5(previous) && isPlainObject5(value)) {
76873
+ edits.push(...diffEdits(previous, value, nextPath));
76874
+ continue;
76875
+ }
76876
+ edits.push({ path: nextPath, value });
76877
+ }
76878
+ return edits;
76879
+ }
76880
+ var init_diff_edits = __esm(() => {
76881
+ init_plain_object();
76882
+ });
76883
+
76425
76884
  // packages/omo-config-core/src/migration/merge.ts
76426
76885
  function displayValue(value) {
76427
76886
  const encoded = JSON.stringify(value);
@@ -76672,17 +77131,11 @@ function prepareTargetReplacement(input) {
76672
77131
  const marker = markerValue(input.target, input.migrationId, input.targetPath);
76673
77132
  const document = { ...documentCleanup.document, _migrations: marker };
76674
77133
  validateTarget(input.targetPath, document);
76675
- const edits = [...targetCleanup.edits];
76676
- for (const key of Object.keys(targetCleanup.document)) {
76677
- if (key !== "_migrations" && !Object.prototype.hasOwnProperty.call(documentCleanup.document, key)) {
76678
- edits.push({ path: [key], value: undefined });
76679
- }
76680
- }
76681
- for (const [key, value] of Object.entries(documentCleanup.document)) {
76682
- if (key !== "_migrations")
76683
- edits.push({ path: [key], value });
76684
- }
76685
- edits.push({ path: ["_migrations"], value: marker });
77134
+ const edits = [
77135
+ ...targetCleanup.edits,
77136
+ ...diffEdits(withoutMarker(targetCleanup.document), withoutMarker(documentCleanup.document)),
77137
+ { path: ["_migrations"], value: marker }
77138
+ ];
76686
77139
  return {
76687
77140
  diagnostics: uniqueDiagnostics([...targetCleanup.diagnostics, ...documentCleanup.diagnostics]),
76688
77141
  document,
@@ -76717,6 +77170,7 @@ var init_commit = __esm(() => {
76717
77170
  init_loader3();
76718
77171
  init_schema();
76719
77172
  init_writer2();
77173
+ init_diff_edits();
76720
77174
  init_merge2();
76721
77175
  init_types5();
76722
77176
  OMO_HARNESS_BLOCKS = [...OMO_CONFIG_HARNESS_IDS, ...OMO_CONFIG_LEGACY_HARNESS_IDS].map(harnessBlockKey);
@@ -78015,7 +78469,7 @@ function generateModelConfig(config) {
78015
78469
  if (avail.native.openai) {
78016
78470
  agentConfig = { model: "openai/gpt-6-luna-fast", variant: "low" };
78017
78471
  } else if (avail.native.claude) {
78018
- agentConfig = { model: "anthropic/claude-haiku-4-5" };
78472
+ agentConfig = { model: "anthropic/claude-haiku-5-5", variant: "medium" };
78019
78473
  } else if (avail.opencodeZen) {
78020
78474
  agentConfig = { model: "opencode/gpt-5-nano" };
78021
78475
  } else if (avail.opencodeGo) {
@@ -89519,7 +89973,7 @@ var package_default2;
89519
89973
  var init_package2 = __esm(() => {
89520
89974
  package_default2 = {
89521
89975
  name: "@oh-my-opencode/omo-codex",
89522
- version: "5.1.27",
89976
+ version: "5.1.29",
89523
89977
  type: "module",
89524
89978
  private: true,
89525
89979
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",