oh-my-opencode 5.0.0-beta.18 → 5.0.0-beta.19

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 (143) hide show
  1. package/dist/cli/index.js +289 -160
  2. package/dist/cli-node/index.js +289 -160
  3. package/dist/index.js +324 -176
  4. package/dist/skills/ast-grep/AGENTS.md +51 -0
  5. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  6. package/dist/skills/start-work/SKILL.md +2 -1
  7. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  8. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +2 -0
  9. package/dist/skills/visual-qa/AGENTS.md +58 -0
  10. package/dist/tui.js +17 -17
  11. package/package.json +21 -21
  12. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  13. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  14. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  15. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  16. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  17. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  18. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  19. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  20. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  21. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  22. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  23. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  24. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  25. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  27. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  28. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  29. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  30. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  32. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +1 -4
  33. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  34. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  35. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  36. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  37. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  38. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  39. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  40. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  41. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  42. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  43. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  44. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  45. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  46. package/packages/omo-codex/plugin/components/rules/dist/cli.js +43 -30
  47. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  48. package/packages/omo-codex/plugin/components/rules/package.json +2 -2
  49. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  50. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  51. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +6 -2
  52. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  53. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  54. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +1 -2
  55. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  56. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  57. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  58. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +2 -3
  59. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  60. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  61. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  62. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  63. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +1 -2
  64. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  65. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  66. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  67. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +1 -2
  68. package/packages/omo-codex/plugin/components/start-work-continuation/biome.json +2 -2
  69. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  70. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  71. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  72. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  73. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  74. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  75. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +237 -99
  76. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +237 -99
  77. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  78. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  79. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  80. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  81. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  82. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  83. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  84. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  85. package/packages/omo-codex/plugin/components/ultrawork/directive.md +7 -1
  86. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  87. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  88. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +7 -1
  89. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  90. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +16 -0
  91. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  92. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +7 -1
  93. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +1 -1
  94. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  95. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  96. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  97. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  98. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  99. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  100. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +3 -2
  101. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  102. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  115. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  116. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  117. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  118. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  119. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  120. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  121. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  122. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  123. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  124. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  125. package/packages/omo-codex/plugin/package-lock.json +19 -19
  126. package/packages/omo-codex/plugin/package.json +1 -1
  127. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  128. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  129. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  130. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +2 -1
  131. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  132. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +2 -0
  133. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +7 -1
  134. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  135. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  136. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  137. package/packages/omo-codex/scripts/install-dist/install-local.mjs +249 -120
  138. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  139. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  140. package/packages/shared-skills/skills/start-work/SKILL.md +2 -1
  141. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  142. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +2 -0
  143. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
@@ -1,9 +1,9 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.5.9/schema.json",
3
3
  "linter": {
4
4
  "enabled": true,
5
5
  "rules": {
6
- "recommended": true,
6
+ "preset": "recommended",
7
7
  "style": {
8
8
  "noDefaultExport": "error",
9
9
  "noEnum": "error",
@@ -66,11 +66,7 @@ function isRecord(value) {
66
66
  var SUBAGENT_STOP_EVENT = "SubagentStop";
67
67
 
68
68
  // components/lazycodex-executor-verify/src/codex-hook.ts
69
- var RECEIPT_ENFORCED_AGENTS = new Set([
70
- "lazycodex-worker-low",
71
- "lazycodex-worker-medium",
72
- "lazycodex-worker-high"
73
- ]);
69
+ var RECEIPT_ENFORCED_AGENTS = new Set(["lazycodex-worker-low", "lazycodex-worker-medium", "lazycodex-worker-high"]);
74
70
  function runSubagentStopHook(input, fs) {
75
71
  if (!isSubagentStopInput(input))
76
72
  return "";
@@ -3,11 +3,7 @@ import { isAbsolute, relative, resolve } from "node:path";
3
3
  import { renderDirective } from "./directive.js";
4
4
  import { clearAttemptState, MAX_ATTEMPTS, readAttemptState, writeAttemptState } from "./state.js";
5
5
  import { SUBAGENT_STOP_EVENT } from "./types.js";
6
- const RECEIPT_ENFORCED_AGENTS = new Set([
7
- "lazycodex-worker-low",
8
- "lazycodex-worker-medium",
9
- "lazycodex-worker-high",
10
- ]);
6
+ const RECEIPT_ENFORCED_AGENTS = new Set(["lazycodex-worker-low", "lazycodex-worker-medium", "lazycodex-worker-high"]);
11
7
  export function runSubagentStopHook(input, fs) {
12
8
  if (!isSubagentStopInput(input))
13
9
  return "";
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO 5.0.0-beta.18) Verifying LazyCodex Executor Evidence"
11
+ "statusMessage": "(OmO 5.0.0-beta.19) Verifying LazyCodex Executor Evidence"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lazycodex-executor-verify",
3
- "version": "5.0.0-beta.18",
3
+ "version": "5.0.0-beta.19",
4
4
  "description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -6,11 +6,7 @@ import { clearAttemptState, MAX_ATTEMPTS, readAttemptState, writeAttemptState }
6
6
  import type { HookFileSystem, StopHookOutput, SubagentStopInput } from "./types.js";
7
7
  import { SUBAGENT_STOP_EVENT } from "./types.js";
8
8
 
9
- const RECEIPT_ENFORCED_AGENTS = new Set([
10
- "lazycodex-worker-low",
11
- "lazycodex-worker-medium",
12
- "lazycodex-worker-high",
13
- ]);
9
+ const RECEIPT_ENFORCED_AGENTS = new Set(["lazycodex-worker-low", "lazycodex-worker-medium", "lazycodex-worker-high"]);
14
10
 
15
11
  export function runSubagentStopHook(input: unknown, fs: HookFileSystem): string {
16
12
  if (!isSubagentStopInput(input)) return "";
@@ -374,9 +374,7 @@ describe("tier worker receipt enforcement", () => {
374
374
 
375
375
  it("#given both hook manifests #when their matchers are applied #then enforced agents match and read-only roles do not", () => {
376
376
  // given
377
- const componentManifest = JSON.parse(
378
- readFileSync(new URL("../hooks/hooks.json", import.meta.url), "utf8"),
379
- );
377
+ const componentManifest = JSON.parse(readFileSync(new URL("../hooks/hooks.json", import.meta.url), "utf8"));
380
378
  const rootManifest = JSON.parse(
381
379
  readFileSync(
382
380
  new URL("../../../hooks/subagent-stop-verifying-lazycodex-executor-evidence.json", import.meta.url),
@@ -394,4 +392,3 @@ describe("tier worker receipt enforcement", () => {
394
392
  }
395
393
  });
396
394
  });
397
-
@@ -1,26 +1,41 @@
1
- # Repository Conventions
1
+ # lsp — Codex LSP integration (PostToolUse diagnostics + MCP routing)
2
2
 
3
- Conventions for humans and agents working on this repository.
3
+ **Generated:** 2026-08-24 (refresh pass)
4
4
 
5
- ## Style
5
+ ## OVERVIEW
6
6
 
7
- - TypeScript strict mode. No `any`, `@ts-ignore`, `@ts-expect-error`, or enums.
8
- - ESM modules with `.js` suffix in import paths.
9
- - Tabs for indentation. Double quotes for strings.
10
- - Runtime is Node only.
11
- - Tests use vitest and should exercise Codex hook/MCP behavior before implementation changes.
7
+ `@code-yeongyu/codex-lsp` (Node >=20). Codex-specific integration only: a `PostToolUse` hook (matcher `^(apply_patch|Write|Edit|MultiEdit|multi_edit|write|edit|multiedit)$`, 60s timeout) that runs error diagnostics on files mutated by edit tools and injects blocking feedback plus the same diagnostics as additional context, and a `PostCompact` hook that resets the per-session diagnostics cache. The LSP/MCP runtime lives upstream: `src/cli.ts` routes the `mcp` subcommand to the vendored repo-root `packages/lsp-tools-mcp/` + `packages/lsp-daemon/` builds (wired via the component `.mcp.json` → `../../../../lsp-daemon/dist/cli.js mcp`); this component consumes `@oh-my-opencode/lsp-core` and `@code-yeongyu/lsp-daemon/client` and stays standalone.
8
+
9
+ Deletes are ignored (cannot introduce new diagnostics); unsupported extensions and clean files emit no hook output.
10
+
11
+ ## KEY FILES
12
+
13
+ | File | Role |
14
+ |------|------|
15
+ | `src/cli.ts` | Entry: routes `mcp` to the upstream runtime; `hook post-tool-use` / `hook post-compact` stay local |
16
+ | `src/codex-hook.ts` | Hook logic: request context, mutated-file extraction, daemon diagnostics call, output shaping (`runLspPostToolUseHook`, `runLspPostCompactHook`, `codexLspRequestContext`) |
17
+ | `src/mutated-file-paths.ts` | Tool-input → file path extraction (`path`/`filePath`/`file_path` aliases, `apply_patch` command parsing) |
18
+ | `src/lsp-session-state.ts` | Per-session post-edit cache, compaction marking, daemon-unreachable detection |
19
+ | `src/daemon-cli-path.ts` | Resolves/vets the lsp-daemon CLI and its env (`resolveLspDaemonCliPath`, `ensureLspDaemonCliEnv`) |
20
+ | `scripts/build-lsp-tools.mjs`, `build-lsp-daemon.mjs`, `build-runtime.mjs` | Vendored upstream builds (run by `prebuild`/`pretest` hooks) |
21
+ | `scripts/test.mjs` | Test driver behind `npm test` |
12
22
 
13
- ## Commands
23
+ ## COMMANDS
14
24
 
15
- - `npm install` installs dependencies.
16
- - `npm test` runs the test suite once.
17
- - `npm run typecheck` runs strict TypeScript checking.
18
- - `npm run check` runs typecheck, Biome, and build.
25
+ - `npm install` then `npm run bootstrap` (builds vendored lsp-tools-mcp + lsp-daemon)
26
+ - `npm test` (builds first, then `node scripts/test.mjs`); `npm run test:watch`
27
+ - `npm run typecheck` / `npm run lint` / `npm run check` (typecheck + Biome + build)
19
28
 
20
29
  ## LSP Constraints
21
30
 
22
- - LSP server processes are owned by `LspManager`.
31
+ - LSP server processes are owned by `LspManager` (upstream runtime).
23
32
  - Tool execution acquires clients through `withLspClient(...)` unless it only reports static status.
24
33
  - `lsp.rename` mutates files by applying workspace edits; keep it sequential at the MCP caller level.
25
- - `.mcp.json` sets `lsp` MCP server `startup_timeout_sec: 10` to bound startup; preserve the bound on edits.
34
+ - `.mcp.json` sets `startup_timeout_sec: 10` to bound startup; preserve the bound on edits.
26
35
  - Do not add pi-coding-agent or omo source dependencies. This package is standalone.
36
+
37
+ ## Style
38
+
39
+ - TypeScript strict mode. No `any`, `@ts-ignore`, `@ts-expect-error`, or enums.
40
+ - ESM modules with `.js` suffix in import paths. Tabs. Double quotes.
41
+ - Runtime is Node only; tests use vitest and should exercise Codex hook/MCP behavior before implementation changes.
@@ -1,9 +1,9 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.5.9/schema.json",
3
3
  "linter": {
4
4
  "enabled": true,
5
5
  "rules": {
6
- "recommended": true,
6
+ "preset": "recommended",
7
7
  "style": {
8
8
  "noDefaultExport": "error",
9
9
  "noEnum": "error",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "5.0.0-beta.18",
4
- "inputDigest": "sha256:bd9b0c82fb18582a00ca28bb1eb0c41ab81bc3837e5e40373f3b3bd8c5410c9a",
3
+ "version": "5.0.0-beta.19",
4
+ "inputDigest": "sha256:5e634463eb1d631e05f8ae13b5d40cbf83c43068b317957dda9c15e09cbbe425",
5
5
  "outputs": [
6
6
  {
7
7
  "path": "cli.d.ts",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  {
35
35
  "path": "daemon-cli-path.js",
36
- "sha256": "5c34353638e95d4a98664c8d23516475e850983e81900aa40e03752946162830"
36
+ "sha256": "96812ddde5100fc408c6109949f07df3df817282dae48428f01a4c3967b4795a"
37
37
  },
38
38
  {
39
39
  "path": "lsp-session-state.d.ts",
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { OMO_LSP_DAEMON_CLI, OMO_LSP_DAEMON_VERSION, resolveDaemonRuntime, } from "@code-yeongyu/lsp-daemon/client";
5
+ import { OMO_LSP_DAEMON_CLI, OMO_LSP_DAEMON_VERSION, resolveDaemonRuntime } from "@code-yeongyu/lsp-daemon/client";
6
6
  const requireFromHere = createRequire(import.meta.url);
7
7
  const PACKAGE_LSP_DAEMON_CLI = "@code-yeongyu/lsp-daemon/cli";
8
8
  export function ensureLspDaemonCliEnv(env = process.env) {
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 60,
11
- "statusMessage": "(OmO 5.0.0-beta.18) Checking LSP Diagnostics"
11
+ "statusMessage": "(OmO 5.0.0-beta.19) Checking LSP Diagnostics"
12
12
  }
13
13
  ]
14
14
  }
@@ -21,7 +21,7 @@
21
21
  "type": "command",
22
22
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
23
23
  "timeout": 5,
24
- "statusMessage": "(OmO 5.0.0-beta.18) Resetting LSP Diagnostics Cache"
24
+ "statusMessage": "(OmO 5.0.0-beta.19) Resetting LSP Diagnostics Cache"
25
25
  }
26
26
  ]
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lsp",
3
- "version": "5.0.0-beta.18",
3
+ "version": "5.0.0-beta.19",
4
4
  "description": "Codex plugin that exposes Language Server Protocol tools and post-edit diagnostics.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -4,7 +4,7 @@ import { join, resolve } from "node:path";
4
4
 
5
5
  import { callDiagnosticsViaDaemon } from "@code-yeongyu/lsp-daemon/client";
6
6
  import { collectPostEditDiagnostics, type PostEditDiagnosticsOutcome } from "@oh-my-opencode/lsp-core/post-edit";
7
- import { parseLspRequestContext, type LspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
7
+ import { type LspRequestContext, parseLspRequestContext } from "@oh-my-opencode/lsp-core/request-context";
8
8
 
9
9
  import { ensureLspDaemonCliEnv } from "./daemon-cli-path.js";
10
10
  import {
@@ -3,11 +3,7 @@ import { createRequire } from "node:module";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
 
6
- import {
7
- OMO_LSP_DAEMON_CLI,
8
- OMO_LSP_DAEMON_VERSION,
9
- resolveDaemonRuntime,
10
- } from "@code-yeongyu/lsp-daemon/client";
6
+ import { OMO_LSP_DAEMON_CLI, OMO_LSP_DAEMON_VERSION, resolveDaemonRuntime } from "@code-yeongyu/lsp-daemon/client";
11
7
 
12
8
  const requireFromHere = createRequire(import.meta.url);
13
9
 
@@ -1,9 +1,8 @@
1
1
  import { mkdtempSync, rmSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import path from "node:path";
4
-
5
- import { afterEach, describe, expect, it } from "vitest";
6
4
  import type { PostEditDiagnosticsOutcome } from "@oh-my-opencode/lsp-core/post-edit";
5
+ import { afterEach, describe, expect, it } from "vitest";
7
6
 
8
7
  import { runLspPostCompactHook, runLspPostToolUseHook } from "../src/codex-hook.js";
9
8
 
@@ -149,11 +148,11 @@ describe("codex PostToolUse unavailable LSP suppression", () => {
149
148
  const input = postToolUseInput("session-daemon-down-probe", ".omo/ulw-loop/evidence/note.md");
150
149
  let calls = 0;
151
150
 
152
- await withPluginData(pluginData, async () => {
153
- await runLspPostToolUseHook(input, async () => {
154
- calls += 1;
155
- return markdownNotConfigured();
156
- });
151
+ await withPluginData(pluginData, async () => {
152
+ await runLspPostToolUseHook(input, async () => {
153
+ calls += 1;
154
+ return markdownNotConfigured();
155
+ });
157
156
  await runLspPostToolUseHook(input, async () => {
158
157
  calls += 1;
159
158
  return "error[markdown] (1000) at 1:1: cached call should have been skipped.";
@@ -1,9 +1,8 @@
1
1
  import { mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import path from "node:path";
4
-
5
- import { afterEach, describe, expect, it } from "vitest";
6
4
  import type { PostEditDiagnosticsOutcome } from "@oh-my-opencode/lsp-core/post-edit";
5
+ import { afterEach, describe, expect, it } from "vitest";
7
6
 
8
7
  import { codexLspRequestContext, extractMutatedFilePaths, runLspPostToolUseHook } from "../src/codex-hook.js";
9
8
 
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
2
2
  import {
3
3
  listDirectoryEntries,
4
4
  readHooksJson,
5
+ readJsonFile,
5
6
  readMcpJson,
6
7
  readPackageJson,
7
8
  readTextFile,
@@ -44,7 +45,16 @@ describe("plugin package metadata", () => {
44
45
  expect(postCompactCommand).toBe(`node "${pluginRoot}/dist/cli.js" hook post-compact`);
45
46
  expect(lspServer?.command).toBe("node");
46
47
  expect(lspServer?.args).toEqual(["../../../../lsp-daemon/dist/cli.js", "mcp"]);
47
- expect(lspServer?.startup_timeout_sec).toBe(10);
48
+ expect(readJsonFile(".mcp.json")).toEqual({
49
+ mcpServers: {
50
+ lsp: {
51
+ command: "node",
52
+ args: ["../../../../lsp-daemon/dist/cli.js", "mcp"],
53
+ cwd: ".",
54
+ startup_timeout_sec: 10,
55
+ },
56
+ },
57
+ });
48
58
  expect(cliSource).not.toContain("./lazy-lsp-mcp.js");
49
59
  expect(cliSource).toContain("resolveLspDaemonCliPath");
50
60
  expect(daemonCliPathSource).toContain("@code-yeongyu/lsp-daemon/cli");
@@ -10,6 +10,17 @@ Conventions for human contributors and AI agents working on this repository.
10
10
  - Tabs for indentation. Double quotes for strings.
11
11
  - Tests use vitest with `#given .. #when .. #then` descriptions or plain `// given / // when / // then` body comments.
12
12
 
13
+ ## Layout
14
+
15
+ - `src/cli.ts`: bin `omo-rules`; routes `hook session-start` / `hook user-prompt-submit` / `hook post-tool-use` / `hook post-compact`.
16
+ - `src/codex-hook.ts`: the four lifecycle hook functions (`runSessionStartHook`, `runUserPromptSubmitHook`, `runPostToolUseHook`, `runPostCompactHook`) — config, engine load, budgets, dedup, output formatting. Main behavioral hotspot.
17
+ - `src/persistent-cache.ts` + `src/session-state-lock.ts`: persisted static/dynamic dedup, target fingerprints, post-compact claims (`withPostCompactBudget`, `claimPostCompactPending`), `withSessionStateLock` (`SESSION_STATE_LOCK_CONTENDED`).
18
+ - `src/tool-paths.ts`: Codex file path extraction for reads, edits, `apply_patch`, shell-style tools (`extractCodexToolPaths`).
19
+ - `src/transcript-search.ts` / `src/transcript-rule-filter.ts`: transcript scanning and filtering.
20
+ - `src/rules-engine-factory.ts`: bridges `@oh-my-opencode/rules-engine` (discovery, parsing, matching, config).
21
+ - `bundled-rules/`: shipped Markdown rules (`hephaestus/`, `windows-git-bash.md`); ordering and platform candidates pinned by tests.
22
+ - `hooks/hooks.json`: registration. `scripts/bench-codex-rules.mjs`: benchmark.
23
+
13
24
  ## Commands
14
25
 
15
26
  - `npm install` - install dependencies.
@@ -17,6 +28,7 @@ Conventions for human contributors and AI agents working on this repository.
17
28
  - `npm run typecheck` - strict TypeScript check.
18
29
  - `npm run check` - type check, biome, and build.
19
30
  - `npm pack --dry-run` - release package smoke test.
31
+ - `npm run bench` - builds then runs the rules benchmark (`node scripts/bench-codex-rules.mjs`).
20
32
  - `node dist/cli.js hook session-start < fixture.json` - smoke-test static rule injection.
21
33
  - `node dist/cli.js hook post-tool-use < fixture.json` - smoke-test dynamic rule injection.
22
34
 
@@ -1,9 +1,9 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.5.9/schema.json",
3
3
  "linter": {
4
4
  "enabled": true,
5
5
  "rules": {
6
- "recommended": true,
6
+ "preset": "recommended",
7
7
  "style": {
8
8
  "noDefaultExport": "error",
9
9
  "noEnum": "error",
@@ -33,7 +33,7 @@ var __toESM = (mod, isNodeMode, target) => {
33
33
  };
34
34
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
35
35
 
36
- // ../../../node_modules/.bun/picomatch@4.0.5/node_modules/picomatch/lib/constants.js
36
+ // ../../../node_modules/.bun/picomatch@4.0.7/node_modules/picomatch/lib/constants.js
37
37
  var require_constants = __commonJS(function(exports, module) {
38
38
  var WIN_SLASH = "\\\\/";
39
39
  var WIN_NO_SLASH = `[^${WIN_SLASH}]`;
@@ -178,7 +178,7 @@ var require_constants = __commonJS(function(exports, module) {
178
178
  };
179
179
  });
180
180
 
181
- // ../../../node_modules/.bun/picomatch@4.0.5/node_modules/picomatch/lib/utils.js
181
+ // ../../../node_modules/.bun/picomatch@4.0.7/node_modules/picomatch/lib/utils.js
182
182
  var require_utils = __commonJS(function(exports) {
183
183
  var {
184
184
  REGEX_BACKSLASH,
@@ -241,7 +241,7 @@ var require_utils = __commonJS(function(exports) {
241
241
  };
242
242
  });
243
243
 
244
- // ../../../node_modules/.bun/picomatch@4.0.5/node_modules/picomatch/lib/scan.js
244
+ // ../../../node_modules/.bun/picomatch@4.0.7/node_modules/picomatch/lib/scan.js
245
245
  var require_scan = __commonJS(function(exports, module) {
246
246
  var utils = require_utils();
247
247
  var {
@@ -272,7 +272,7 @@ var require_scan = __commonJS(function(exports, module) {
272
272
  var scan = (input, options) => {
273
273
  const opts = options || {};
274
274
  const length = input.length - 1;
275
- const scanToEnd = opts.parts === true || opts.scanToEnd === true;
275
+ const scanToEnd = opts.parts === true || opts.tokens === true || opts.scanToEnd === true;
276
276
  const slashes = [];
277
277
  const tokens = [];
278
278
  const parts = [];
@@ -379,14 +379,18 @@ var require_scan = __commonJS(function(exports, module) {
379
379
  negatedExtglob = true;
380
380
  }
381
381
  if (scanToEnd === true) {
382
+ let parens = 0;
382
383
  while (eos() !== true && (code = advance())) {
383
384
  if (code === CHAR_BACKWARD_SLASH) {
384
385
  backslashes = token.backslashes = true;
385
- code = advance();
386
+ advance();
387
+ continue;
388
+ }
389
+ if (code === CHAR_LEFT_PARENTHESES) {
390
+ parens++;
386
391
  continue;
387
392
  }
388
- if (code === CHAR_RIGHT_PARENTHESES) {
389
- isGlob = token.isGlob = true;
393
+ if (code === CHAR_RIGHT_PARENTHESES && --parens === 0) {
390
394
  finished = true;
391
395
  break;
392
396
  }
@@ -441,13 +445,18 @@ var require_scan = __commonJS(function(exports, module) {
441
445
  if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
442
446
  isGlob = token.isGlob = true;
443
447
  if (scanToEnd === true) {
448
+ let parens = 1;
444
449
  while (eos() !== true && (code = advance())) {
445
- if (code === CHAR_LEFT_PARENTHESES) {
450
+ if (code === CHAR_BACKWARD_SLASH) {
446
451
  backslashes = token.backslashes = true;
447
- code = advance();
452
+ advance();
453
+ continue;
454
+ }
455
+ if (code === CHAR_LEFT_PARENTHESES) {
456
+ parens++;
448
457
  continue;
449
458
  }
450
- if (code === CHAR_RIGHT_PARENTHESES) {
459
+ if (code === CHAR_RIGHT_PARENTHESES && --parens === 0) {
451
460
  finished = true;
452
461
  break;
453
462
  }
@@ -521,32 +530,31 @@ var require_scan = __commonJS(function(exports, module) {
521
530
  if (opts.parts === true || opts.tokens === true) {
522
531
  let prevIndex;
523
532
  for (let idx = 0;idx < slashes.length; idx++) {
524
- const n = prevIndex ? prevIndex + 1 : start;
533
+ const n2 = prevIndex !== undefined ? prevIndex + 1 : start;
525
534
  const i = slashes[idx];
526
- const value = input.slice(n, i);
535
+ const value2 = input.slice(n2, i);
527
536
  if (opts.tokens) {
528
537
  if (idx === 0 && start !== 0) {
529
538
  tokens[idx].isPrefix = true;
530
539
  tokens[idx].value = prefix;
531
540
  } else {
532
- tokens[idx].value = value;
541
+ tokens[idx].value = value2;
533
542
  }
534
543
  depth(tokens[idx]);
535
544
  state.maxDepth += tokens[idx].depth;
536
545
  }
537
- if (idx !== 0 || value !== "") {
538
- parts.push(value);
546
+ if (i >= start) {
547
+ parts.push(value2);
548
+ prevIndex = i;
539
549
  }
540
- prevIndex = i;
541
550
  }
542
- if (prevIndex && prevIndex + 1 < input.length) {
543
- const value = input.slice(prevIndex + 1);
544
- parts.push(value);
545
- if (opts.tokens) {
546
- tokens[tokens.length - 1].value = value;
547
- depth(tokens[tokens.length - 1]);
548
- state.maxDepth += tokens[tokens.length - 1].depth;
549
- }
551
+ const n = prevIndex !== undefined ? prevIndex + 1 : start;
552
+ const value = input.slice(n);
553
+ parts.push(value);
554
+ if (opts.tokens && prevIndex && prevIndex + 1 < input.length) {
555
+ tokens[tokens.length - 1].value = value;
556
+ depth(tokens[tokens.length - 1]);
557
+ state.maxDepth += tokens[tokens.length - 1].depth;
550
558
  }
551
559
  state.slashes = slashes;
552
560
  state.parts = parts;
@@ -556,7 +564,7 @@ var require_scan = __commonJS(function(exports, module) {
556
564
  module.exports = scan;
557
565
  });
558
566
 
559
- // ../../../node_modules/.bun/picomatch@4.0.5/node_modules/picomatch/lib/parse.js
567
+ // ../../../node_modules/.bun/picomatch@4.0.7/node_modules/picomatch/lib/parse.js
560
568
  var require_parse = __commonJS(function(exports, module) {
561
569
  var constants = require_constants();
562
570
  var utils = require_utils();
@@ -1388,6 +1396,7 @@ var require_parse = __commonJS(function(exports, module) {
1388
1396
  rest = rest.slice(3);
1389
1397
  consume("/**", 3);
1390
1398
  }
1399
+ const isEnd = eos() || state.parens > 0 && rest === ")".repeat(state.parens) && !extglobs.some((extglob) => extglob.type === "negate");
1391
1400
  if (prior.type === "bos" && eos()) {
1392
1401
  prev.type = "globstar";
1393
1402
  prev.value += value;
@@ -1397,7 +1406,7 @@ var require_parse = __commonJS(function(exports, module) {
1397
1406
  consume(value);
1398
1407
  continue;
1399
1408
  }
1400
- if (prior.type === "slash" && prior.prev.type !== "bos" && !afterStar && eos()) {
1409
+ if (prior.type === "slash" && prior.prev.type !== "bos" && !afterStar && isEnd) {
1401
1410
  state.output = state.output.slice(0, -(prior.output + prev.output).length);
1402
1411
  prior.output = `(?:${prior.output}`;
1403
1412
  prev.type = "globstar";
@@ -1575,7 +1584,7 @@ var require_parse = __commonJS(function(exports, module) {
1575
1584
  module.exports = parse;
1576
1585
  });
1577
1586
 
1578
- // ../../../node_modules/.bun/picomatch@4.0.5/node_modules/picomatch/lib/picomatch.js
1587
+ // ../../../node_modules/.bun/picomatch@4.0.7/node_modules/picomatch/lib/picomatch.js
1579
1588
  var require_picomatch = __commonJS(function(exports, module) {
1580
1589
  var scan = require_scan();
1581
1590
  var parse = require_parse();
@@ -1715,7 +1724,7 @@ var require_picomatch = __commonJS(function(exports, module) {
1715
1724
  module.exports = picomatch;
1716
1725
  });
1717
1726
 
1718
- // ../../../node_modules/.bun/picomatch@4.0.5/node_modules/picomatch/index.js
1727
+ // ../../../node_modules/.bun/picomatch@4.0.7/node_modules/picomatch/index.js
1719
1728
  var require_picomatch2 = __commonJS(function(exports, module) {
1720
1729
  var pico = require_picomatch();
1721
1730
  var utils = require_utils();
@@ -3885,7 +3894,11 @@ var MODEL_CONTEXT_BUDGETS = [
3885
3894
  effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT
3886
3895
  },
3887
3896
  { slug: "gpt-5.5", contextWindowTokens: 272000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
3888
- { slug: "gpt-5.6-luna-fast", contextWindowTokens: 272000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
3897
+ {
3898
+ slug: "gpt-5.6-luna-fast",
3899
+ contextWindowTokens: 272000,
3900
+ effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT
3901
+ },
3889
3902
  {
3890
3903
  slug: "codex-auto-review",
3891
3904
  contextWindowTokens: 272000,
@@ -4148,7 +4161,7 @@ function recoverDynamicRulePaths(engine, transcriptText, staticRules) {
4148
4161
  if (staticRulePaths.has(rulePath)) {
4149
4162
  continue;
4150
4163
  }
4151
- if (transcriptText !== null && transcriptText.includes(rulePath)) {
4164
+ if (transcriptText?.includes(rulePath)) {
4152
4165
  continue;
4153
4166
  }
4154
4167
  if (!existsSync4(rulePath)) {
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.18) Loading Project Rules"
10
+ "statusMessage": "(OmO 5.0.0-beta.19) Loading Project Rules"
11
11
  }
12
12
  ]
13
13
  }
@@ -19,7 +19,7 @@
19
19
  "type": "command",
20
20
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
21
21
  "timeout": 10,
22
- "statusMessage": "(OmO 5.0.0-beta.18) Loading Project Rules"
22
+ "statusMessage": "(OmO 5.0.0-beta.19) Loading Project Rules"
23
23
  }
24
24
  ]
25
25
  }
@@ -32,7 +32,7 @@
32
32
  "type": "command",
33
33
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
34
34
  "timeout": 10,
35
- "statusMessage": "(OmO 5.0.0-beta.18) Matching Project Rules"
35
+ "statusMessage": "(OmO 5.0.0-beta.19) Matching Project Rules"
36
36
  }
37
37
  ]
38
38
  }
@@ -45,7 +45,7 @@
45
45
  "type": "command",
46
46
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
47
47
  "timeout": 10,
48
- "statusMessage": "(OmO 5.0.0-beta.18) Resetting Project Rule Cache"
48
+ "statusMessage": "(OmO 5.0.0-beta.19) Resetting Project Rule Cache"
49
49
  }
50
50
  ]
51
51
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-rules",
3
- "version": "5.0.0-beta.18",
3
+ "version": "5.0.0-beta.19",
4
4
  "description": "Codex plugin that injects project rule files into model context through lifecycle hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -47,7 +47,7 @@
47
47
  "check": "tsc --noEmit && biome check . && npm run build"
48
48
  },
49
49
  "dependencies": {
50
- "picomatch": "^4.0.5"
50
+ "picomatch": "^4.0.7"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@oh-my-opencode/rules-engine": "file:../../../../rules-engine",
@@ -1,6 +1,5 @@
1
- import { SOURCE_PRIORITY } from "@oh-my-opencode/rules-engine/engine";
2
- import { defaultConfig } from "@oh-my-opencode/rules-engine/engine";
3
1
  import type { PiRulesConfig, RuleSource } from "@oh-my-opencode/rules-engine/engine";
2
+ import { defaultConfig, SOURCE_PRIORITY } from "@oh-my-opencode/rules-engine/engine";
4
3
 
5
4
  export function configFromEnvironment(env: NodeJS.ProcessEnv = process.env): PiRulesConfig {
6
5
  const config = defaultConfig();
@@ -1,7 +1,7 @@
1
1
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
-
4
+ import type { Engine } from "@oh-my-opencode/rules-engine/engine";
5
5
  import {
6
6
  type PostCompactPendingKind,
7
7
  type PostCompactPendingState,
@@ -9,7 +9,6 @@ import {
9
9
  postCompactPendingKinds,
10
10
  postCompactRecoveringKinds,
11
11
  } from "./post-compact-state.js";
12
- import type { Engine } from "@oh-my-opencode/rules-engine/engine";
13
12
  import { SESSION_STATE_LOCK_CONTENDED, withSessionStateLock } from "./session-state-lock.js";
14
13
 
15
14
  export type PostCompactClaimResult = "claimed" | "not-pending" | "contended";
@@ -1,5 +1,5 @@
1
- import { hasContextPressureMarker } from "./context-pressure.js";
2
1
  import type { PiRulesConfig } from "@oh-my-opencode/rules-engine/engine";
2
+ import { hasContextPressureMarker } from "./context-pressure.js";
3
3
  import { readTranscriptSearchText } from "./transcript-search.js";
4
4
 
5
5
  export interface PostCompactBudgetContext {
@@ -33,7 +33,11 @@ const MODEL_CONTEXT_BUDGETS: readonly ModelContextBudget[] = [
33
33
  effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT,
34
34
  },
35
35
  { slug: "gpt-5.5", contextWindowTokens: 272_000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
36
- { slug: "gpt-5.6-luna-fast", contextWindowTokens: 272_000, effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT },
36
+ {
37
+ slug: "gpt-5.6-luna-fast",
38
+ contextWindowTokens: 272_000,
39
+ effectivePercent: DEFAULT_EFFECTIVE_CONTEXT_WINDOW_PERCENT,
40
+ },
37
41
  {
38
42
  slug: "codex-auto-review",
39
43
  contextWindowTokens: 272_000,