oh-my-opencode 5.1.57 → 5.1.59

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 (83) hide show
  1. package/dist/cli/index.js +49 -45
  2. package/dist/cli-node/index.js +49 -45
  3. package/dist/index.js +364 -282
  4. package/dist/skills/browser/runtime/omowright/index.js +20 -19
  5. package/dist/skills/browser/runtime/omowright/manifest.json +3 -3
  6. package/dist/skills/eval-integrity/SKILL.md +107 -0
  7. package/dist/skills/ultimate-browsing/engine/executor.py +56 -5
  8. package/dist/skills/ultimate-browsing/engine/tests/test_executor_timeout.py +144 -0
  9. package/dist/skills/ulw-research/scripts/fidelity-values.mjs +5 -2
  10. package/dist/skills/ulw-research/scripts/fidelity-values.test.ts +26 -0
  11. package/dist/skills/ulw-research/scripts/html-foreign-object.mjs +61 -0
  12. package/dist/skills/ulw-research/scripts/html-lite.mjs +7 -3
  13. package/dist/skills/ulw-research/scripts/html-lite.test.ts +19 -0
  14. package/dist/tui.js +44 -40
  15. package/package.json +15 -15
  16. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  17. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +5 -1
  18. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  19. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  20. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  21. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  22. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  23. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  25. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  27. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  28. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  29. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  30. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  32. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  34. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  36. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  38. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  39. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  40. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  41. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  42. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  43. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  44. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  45. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  46. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  47. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  52. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  53. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  54. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  55. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  56. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  57. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  58. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  59. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  60. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  61. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  62. package/packages/omo-codex/plugin/package-lock.json +12 -12
  63. package/packages/omo-codex/plugin/package.json +1 -1
  64. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +20 -19
  65. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +3 -3
  66. package/packages/omo-codex/plugin/skills/eval-integrity/SKILL.md +107 -0
  67. package/packages/omo-codex/plugin/skills/eval-integrity/agents/openai.yaml +2 -0
  68. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/executor.py +56 -5
  69. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-values.mjs +5 -2
  70. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-foreign-object.mjs +61 -0
  71. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-lite.mjs +7 -3
  72. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -0
  73. package/packages/omo-codex/scripts/install-dist/install-local.mjs +7 -3
  74. package/packages/shared-skills/skills/browser/runtime/omowright/index.js +20 -19
  75. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +3 -3
  76. package/packages/shared-skills/skills/eval-integrity/SKILL.md +107 -0
  77. package/packages/shared-skills/skills/ultimate-browsing/engine/executor.py +56 -5
  78. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_executor_timeout.py +144 -0
  79. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.mjs +5 -2
  80. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.test.ts +26 -0
  81. package/packages/shared-skills/skills/ulw-research/scripts/html-foreign-object.mjs +61 -0
  82. package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +7 -3
  83. package/packages/shared-skills/skills/ulw-research/scripts/html-lite.test.ts +19 -0
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "version": "0.0.1",
3
- "sourceDigest": "c9eaae75e948cc52d5b60bb654a5565869d68627046453d87d6f695a5b618045",
3
+ "sourceDigest": "27243299c68de06d4321588d998bd106e0554086d268dc448aa70571db719c1d",
4
4
  "files": {
5
- "index.js": "8b14c1775f397e36967a0d094c67e2a31f8ae1e92add172925548723ca339046",
5
+ "index.js": "3a2e4f2575bdfc15448f13768cd8113f8493bf04611c9fefb09b13430d6520de",
6
6
  "page-bundle.js": "bfd51e8383cf47200d57387bbbed258bce5a3a3d00c38fc108034d2888e23f0c"
7
7
  },
8
- "stagedAtUtc": "2026-11-01T20:36:54.907Z"
8
+ "stagedAtUtc": "2026-11-03T09:03:26.434Z"
9
9
  }
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: eval-integrity
3
+ description: "Assess integrity of an eval, benchmark, metric, A/B test, holdout, LLM-judge, or user-study claim when the question is whether measurement, comparison, or evidence is independent and trustworthy."
4
+ ---
5
+
6
+ # Evaluation Integrity
7
+
8
+ Provide a read-only audit of whether an evaluation can support its stated claim. Do not alter code,
9
+ data, prompts, labels, or study operations. Begin with exactly one verdict line in the form
10
+ `**Verdict: PASS**`, `**Verdict: FAIL**`, or `**Verdict: INCONCLUSIVE**`. Emit no other verdict
11
+ line and do not restate the verdict later in the report. A favorable score is not itself evidence
12
+ of integrity.
13
+
14
+ ## Route correctly
15
+
16
+ - **NOT for code review:** route implementation, correctness, security, or maintainability review to
17
+ `review-work`.
18
+ - **NOT for data processing:** route cleaning, transforming, joining, modeling, or analyzing data to
19
+ `data-scientist`.
20
+ - Use this skill for the independence and validity of the measurement setup, not for producing a
21
+ result from it.
22
+
23
+ ## Audit method
24
+
25
+ ### 1. State the claim and map the evaluation
26
+
27
+ Write the claim in testable form: what comparison, metric, threshold, or causal statement is being
28
+ made; for which population; and under which decision rule. Map every role before judging it:
29
+
30
+ | Element | Record |
31
+ | --- | --- |
32
+ | Claim | The conclusion and decision it is meant to justify. |
33
+ | System under test | Exact model, version, configuration, prompt, policy, or treatment. |
34
+ | Dataset and split | Sources, collection dates, inclusion rules, train/dev/test or holdout assignment. |
35
+ | Designer | Who selected the task, data, prompts, treatments, metric, and stopping rule. |
36
+ | Evaluator or judge | Who or what assigns quality judgments, including model and prompt versions. |
37
+ | Scorer | The rule or system that turns outputs or judgments into the reported metric. |
38
+ | Subjects | Humans, records, tasks, or units exposed to treatment or observation. |
39
+
40
+ Trace shared ownership, shared data, shared prompts, shared labels, and shared selection decisions
41
+ across this map. Several models do **not** establish independence merely because there are several
42
+ of them; identify distinct training, tuning, prompt design, labels, data, and decision authority.
43
+
44
+ ### 2. Check the ground truth
45
+
46
+ Identify the independent ground truth that could confirm the claim without reusing the system's own
47
+ preferences, outputs, labels, or optimization target. Test whether it is:
48
+
49
+ - external to the system under test and its designer;
50
+ - collected or adjudicated without seeing the treatment identity when blinding is feasible;
51
+ - appropriate to the claim rather than a proxy selected because it favors one arm; and
52
+ - fixed before comparison, or accompanied by a disclosed multiplicity and selection procedure.
53
+
54
+ If no independent ground truth exists, do not substitute agreement among related systems. Mark the
55
+ claim **INCONCLUSIVE** unless the stated claim is explicitly limited to that related system's score.
56
+
57
+ ### 3. Probe independence failures
58
+
59
+ Check only risks relevant to the mapped design:
60
+
61
+ - **Contamination:** benchmark items, answers, or near duplicates reached training, prompt design,
62
+ retrieval, tuning, or post-hoc selection.
63
+ - **Invalid controls:** arms differ beyond the intended treatment, allocation is biased, exposure is
64
+ unequal, or the control cannot answer the causal comparison.
65
+ - **Circular judging:** the evaluated system, its designer, or a derived rubric defines its own
66
+ success without external confirmation.
67
+ - **Scorer-label coupling:** labels, thresholds, reward signals, or rubric choices are reused by the
68
+ scorer in a way that makes agreement self-fulfilling.
69
+ - **Evaluator-designer coupling:** the evaluator, judge prompt, or adjudication process is selected,
70
+ tuned, or influenced by the comparison designer without an independent safeguard.
71
+ - **Split or annotator dependence:** overlapping sources, duplicates, temporal leakage, shared
72
+ annotators, or correlated annotation policies invalidate assumed independence.
73
+ - **Hypothesis priming:** task framing, examples, pre-registration gaps, or interim results steer
74
+ evaluators or analysts toward the expected outcome.
75
+ - **Observer and demand effects:** subjects or observers infer the desired treatment or outcome, and
76
+ behavior or ratings change because of that knowledge.
77
+
78
+ For each concern, distinguish documented evidence from an assumption. Missing provenance for data,
79
+ splits, labels, prompts, evaluator selection, or scoring is **INCONCLUSIVE**, not evidence that the
80
+ design was independent.
81
+
82
+ ### 4. Reach the verdict
83
+
84
+ - **PASS:** evidence supports an independent, valid measurement path for the stated claim, with no
85
+ material unresolved dependency.
86
+ - **FAIL:** evidence shows a dependency or invalid design that materially invalidates or overstates
87
+ the stated claim.
88
+ - **INCONCLUSIVE:** provenance or evidence is missing, the ground truth is not independently
89
+ established, or remaining uncertainty prevents either result.
90
+
91
+ Do not convert uncertainty into PASS because a metric looks plausible, a result is statistically
92
+ significant, or multiple related evaluators agree.
93
+
94
+ ## Report
95
+
96
+ Report the verdict first. Then report only findings that fired; do not pad the report with risks
97
+ that were checked and did not fire. For each fired finding include:
98
+
99
+ 1. **Evidence:** the observed artifact, provenance record, or explicit absence of one.
100
+ 2. **Impact:** which claim or inference the issue weakens or invalidates.
101
+ 3. **Minimal independence fix:** the smallest separation, blind, held-out source, external
102
+ adjudication, or control change that would address it.
103
+ 4. **Missing evidence:** what must be supplied to resolve the finding, if applicable.
104
+ 5. **Residual risk:** what remains uncertain after the minimal fix.
105
+
106
+ Keep conclusions bounded to the evidence. This audit advises; it does not certify a system,
107
+ recompute results, or approve deployment.
@@ -0,0 +1,2 @@
1
+ interface:
2
+ display_name: "(OmO) eval-integrity"
@@ -21,6 +21,7 @@ from __future__ import annotations
21
21
  import json
22
22
  import os
23
23
  import shutil
24
+ import signal
24
25
  import subprocess
25
26
  import tempfile
26
27
  import time
@@ -32,6 +33,10 @@ from .result_schema import Attempt
32
33
 
33
34
 
34
35
  TEMPLATES_DIR = os.path.join(os.path.dirname(__file__), "templates")
36
+ # Chrome removes its per-launch state (the macOS code-sign clone, the temp
37
+ # profile) only on a clean quit, so a timed-out template's process group gets
38
+ # SIGTERM and this long to let `ctx.close()` run before SIGKILL (omo#12067).
39
+ TERM_GRACE_S = 5
35
40
 
36
41
 
37
42
  def _node_available() -> bool:
@@ -70,19 +75,65 @@ def _run_node_template(template: str, args: dict, timeout: int = 90) -> tuple[in
70
75
  if not os.path.isfile(path):
71
76
  return 127, "", f"template not found: {path}"
72
77
  try:
73
- proc = subprocess.run(
78
+ proc = subprocess.Popen(
74
79
  ["node", path],
75
- input=json.dumps(args),
80
+ stdin=subprocess.PIPE,
81
+ stdout=subprocess.PIPE,
82
+ stderr=subprocess.PIPE,
76
83
  cwd=TEMPLATES_DIR,
77
- capture_output=True,
78
84
  text=True,
79
- timeout=timeout,
85
+ start_new_session=True,
80
86
  )
81
- return proc.returncode, proc.stdout, proc.stderr
87
+ except Exception as e:
88
+ return 1, "", f"{type(e).__name__}:{e}"
89
+ try:
90
+ stdout, stderr = proc.communicate(input=json.dumps(args), timeout=timeout)
91
+ return proc.returncode, stdout, stderr
82
92
  except subprocess.TimeoutExpired:
93
+ _terminate_template_group(proc)
83
94
  return 124, "", f"timeout after {timeout}s"
84
95
  except Exception as e:
96
+ _terminate_template_group(proc)
85
97
  return 1, "", f"{type(e).__name__}:{e}"
98
+ except BaseException:
99
+ # Cancellation (KeyboardInterrupt, SystemExit): start_new_session keeps a
100
+ # terminal Ctrl-C from reaching the template's group, so quit it here.
101
+ _terminate_template_group(proc)
102
+ raise
103
+
104
+
105
+ def _signal_group(pgid: int, sig: int) -> bool:
106
+ try:
107
+ os.killpg(pgid, sig)
108
+ except ProcessLookupError:
109
+ return False
110
+ return True
111
+
112
+
113
+ def _terminate_template_group(proc: subprocess.Popen[str]) -> None:
114
+ """SIGTERM the template's whole group (node and the Chrome it launched), wait up to TERM_GRACE_S, then SIGKILL."""
115
+ if os.name == "nt":
116
+ proc.terminate()
117
+ try:
118
+ proc.wait(timeout=TERM_GRACE_S)
119
+ except subprocess.TimeoutExpired:
120
+ proc.kill()
121
+ else:
122
+ pgid = proc.pid
123
+ if _signal_group(pgid, signal.SIGTERM):
124
+ deadline = time.monotonic() + TERM_GRACE_S
125
+ while time.monotonic() < deadline:
126
+ proc.poll()
127
+ if not _signal_group(pgid, 0):
128
+ break
129
+ time.sleep(0.05)
130
+ else:
131
+ _signal_group(pgid, signal.SIGKILL)
132
+ try:
133
+ proc.communicate(timeout=TERM_GRACE_S)
134
+ except subprocess.TimeoutExpired:
135
+ proc.kill()
136
+ proc.communicate()
86
137
 
87
138
 
88
139
  class _FakeResp:
@@ -82,13 +82,16 @@ export function exportRows(ledger) {
82
82
 
83
83
  const walk = (node) => node.children.filter((child) => child.tag !== "#text").flatMap((child) => [child, ...walk(child)])
84
84
 
85
- /** SVG text nodes of a chart: data labels, or ticks with their declared grid. */
85
+ /** SVG text nodes of a chart: data labels, or ticks with their declared grid; foreignObject HTML counts as unticked labels. */
86
86
  function svgLabels(raw) {
87
- return walk(parseHtml(raw)).filter((node) => node.tag === "text").map((node) => {
87
+ const nodes = walk(parseHtml(raw))
88
+ const texts = nodes.filter((node) => node.tag === "text").map((node) => {
88
89
  let tick = null
89
90
  for (let cur = node.parent; cur && !tick; cur = cur.parent) if (cur.tag === "g" && /(?:^|\s)ticks(?:\s|$)/.test(cur.attrs.class ?? "")) tick = cur.attrs
90
91
  return { text: proseText(node), tick }
91
92
  })
93
+ const foreign = nodes.filter((node) => node.tag === "foreignobject").map((node) => ({ text: proseText(node), tick: null }))
94
+ return [...texts, ...foreign]
92
95
  }
93
96
 
94
97
  function onGrid(value, tick) {
@@ -0,0 +1,61 @@
1
+ // html-foreign-object.mjs - the <foreignObject> carve-out for the html-lite tokenizer.
2
+ //
3
+ // An <svg> element is raw drawing markup, except <foreignObject>, which by definition holds
4
+ // HTML. The tokenizer keeps the svg's inner source in `raw` and additionally parses each
5
+ // foreignObject subtree into real children of the svg node, so the fidelity checks read chart
6
+ // HTML exactly like prose while the rest of the svg stays raw. Plain Node ESM, no dependencies.
7
+
8
+ import { makeNode, readTag } from "./html-lite.mjs"
9
+
10
+ /** Newlines in text before offset `to`. */
11
+ function newlinesBefore(text, to) {
12
+ let count = 0
13
+ for (let at = text.indexOf("\n"); at !== -1 && at < to; at = text.indexOf("\n", at + 1)) count++
14
+ return count
15
+ }
16
+
17
+ /** Shift a parsed subtree's line numbers by `delta` (fragment lines are relative to the fragment). */
18
+ function shiftLines(node, delta) {
19
+ node.line += delta
20
+ for (const child of node.children) shiftLines(child, delta)
21
+ }
22
+
23
+ const isLetter = (ch) => (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z")
24
+
25
+ /**
26
+ * Parse an svg node's <foreignObject> subtrees into real children; the rest of the svg stays raw.
27
+ * @param {object} node an <svg> LiteNode whose `raw` holds its inner source
28
+ * @param {number} rawStartLine document line of the first raw character
29
+ * @param {(source: string) => object} parseHtml the tokenizer, passed in so this module never imports it back
30
+ */
31
+ export function attachForeignObjects(node, rawStartLine, parseHtml) {
32
+ const raw = node.raw ?? ""
33
+ for (let lt = raw.indexOf("<"); lt !== -1; lt = raw.indexOf("<", lt + 1)) {
34
+ if (raw[lt + 1] === "/" || !isLetter(raw[lt + 1] ?? "")) continue
35
+ const open = readTag(raw, lt + 1)
36
+ if (open.name !== "foreignobject" || open.selfClosing) continue
37
+ let depth = 0
38
+ let innerEnd = raw.length
39
+ let resume = raw.length
40
+ for (let at = raw.indexOf("<", open.end); at !== -1; at = raw.indexOf("<", at + 1)) {
41
+ const closing = raw[at + 1] === "/"
42
+ if (!closing && !isLetter(raw[at + 1] ?? "")) continue
43
+ if (readTag(raw, at + (closing ? 2 : 1)).name !== "foreignobject") continue
44
+ if (closing) {
45
+ if (depth === 0) { innerEnd = at; const gt = raw.indexOf(">", at); resume = gt === -1 ? raw.length : gt + 1; break }
46
+ depth--
47
+ } else depth++
48
+ }
49
+ // Tags are lowercased by readTag, so the attached node is "foreignobject" like any parsed tag.
50
+ const fo = makeNode("foreignobject", open.attrs, node, rawStartLine + newlinesBefore(raw, lt))
51
+ const frag = parseHtml(raw.slice(open.end, innerEnd))
52
+ const body = frag.children.find((child) => child.tag === "body") ?? frag
53
+ for (const child of body.children) {
54
+ child.parent = fo
55
+ shiftLines(child, rawStartLine + newlinesBefore(raw, open.end) - 1)
56
+ fo.children.push(child)
57
+ }
58
+ node.children.push(fo)
59
+ lt = resume - 1
60
+ }
61
+ }
@@ -3,10 +3,13 @@
3
3
  // Single forward scan with indexOf (no whole-document regex, no backtracking). Produces a
4
4
  // LiteNode tree: { tag, attrs, children, parent, line, text, raw }. Text nodes carry
5
5
  // tag "#text"; <style>/<script>/<svg> keep their inner source in `raw` and have no parsed
6
- // children. The "#document" root also carries `ids` (id -> occurrence count) so
7
- // selectorPath can tell whether an id is unique. Plain Node ESM, no dependencies.
6
+ // children, except an <svg> node also gains its <foreignObject> subtrees as parsed children
7
+ // (see html-foreign-object.mjs; the rest of the svg stays raw). The "#document"
8
+ // root also carries `ids` (id -> occurrence count) so selectorPath can tell whether an id
9
+ // is unique. Plain Node ESM, no dependencies.
8
10
 
9
11
  import { decodeEntities } from "./entities.mjs"
12
+ import { attachForeignObjects } from "./html-foreign-object.mjs"
10
13
 
11
14
  export { decodeEntities }
12
15
 
@@ -25,7 +28,7 @@ const SAFE_ID = /^[A-Za-z_][\w-]*$/
25
28
  export const PROSE_TAGS = new Set(["p", "li", ...HEADINGS, "td", "th", "figcaption", "blockquote", "dd", "dt"])
26
29
  export const PROSE_BREAKS = new Set([...P_CLOSERS, ...PROSE_TAGS, "br", "tr"])
27
30
 
28
- function makeNode(tag, attrs, parent, line) {
31
+ export function makeNode(tag, attrs, parent, line) {
29
32
  return { tag, attrs, children: [], parent, line, text: "", raw: null }
30
33
  }
31
34
 
@@ -181,6 +184,7 @@ export function parseHtml(source) {
181
184
  if (!tag.selfClosing) {
182
185
  const [innerEnd, resume] = findRawClose(src, tag.end, tag.name)
183
186
  node.raw = src.slice(tag.end, innerEnd)
187
+ if (tag.name === "svg") attachForeignObjects(node, lineAt(starts, tag.end), parseHtml)
184
188
  at = textStart = resume
185
189
  }
186
190
  } else if (!VOID_TAGS.has(tag.name)) {
@@ -11,6 +11,7 @@ export const expectedSkills = [
11
11
  "comment-checker",
12
12
  "data-scientist",
13
13
  "debugging",
14
+ "eval-integrity",
14
15
  "frontend",
15
16
  "git-master",
16
17
  "init-deep",
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // omo-codex-install:6cf0b2561cf0c247efdca2934fda04149a66e5051fa585f8eda86922b2c111f2:be8844d5b45ec5d54d7f824d3908bcb0d084368c896fb5cf389ce1699543d2aa
2
+ // omo-codex-install:00fcd516729a06a5b4c6c011662edd0382f55eee0b54a318ea2aad7da009a785:dc6523cbcc0b1a234dee5e4e808122583c5a5341eb73f5ea6bdf421e4d71585c
3
3
  var __esm = (fn, res, err) => () => {
4
4
  if (fn)
5
5
  try {
@@ -10205,7 +10205,7 @@ var package_default;
10205
10205
  var init_package = __esm(() => {
10206
10206
  package_default = {
10207
10207
  name: "@oh-my-opencode/omo-codex",
10208
- version: "5.1.57",
10208
+ version: "5.1.59",
10209
10209
  type: "module",
10210
10210
  private: true,
10211
10211
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -19693,7 +19693,11 @@ var OmoCategoryConfigObjectSchema = object({
19693
19693
  disable: boolean2().optional(),
19694
19694
  warn_unavailable: boolean2().optional()
19695
19695
  }).strict();
19696
- var OmoCategoryConfigSchema = preprocess((value) => isRecord4(value) ? normalizeLegacyModelFields(value) : value, OmoCategoryConfigObjectSchema);
19696
+ function withoutRetiredCategoryKeys(entry) {
19697
+ const { provider_lock: _retired, ...rest } = entry;
19698
+ return rest;
19699
+ }
19700
+ var OmoCategoryConfigSchema = preprocess((value) => isRecord4(value) ? withoutRetiredCategoryKeys(normalizeLegacyModelFields(value)) : value, OmoCategoryConfigObjectSchema);
19697
19701
  var OmoCategoriesConfigSchema = record(string2(), OmoCategoryConfigSchema);
19698
19702
 
19699
19703
  // packages/omo-config-core/src/schema/computer.ts