docs(omo-codex): batch 88 (12 files)
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# Normalize line endings: store LF in git, check out LF on every platform.
|
||||
# Required so biome's --check passes on Windows (default core.autocrlf=true).
|
||||
* text=auto eol=lf
|
||||
|
||||
# Explicit binary types
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.zip binary
|
||||
*.tgz binary
|
||||
*.gz binary
|
||||
@@ -0,0 +1,6 @@
|
||||
node_modules/
|
||||
.DS_Store
|
||||
*.log
|
||||
coverage/
|
||||
.vitest/
|
||||
*.tgz
|
||||
@@ -0,0 +1,34 @@
|
||||
# Repository Conventions
|
||||
|
||||
Conventions for human contributors and AI agents working on this repository.
|
||||
|
||||
## Style
|
||||
|
||||
- Terse technical prose. No emojis in commits, issues, PR comments, or code.
|
||||
- TypeScript strict mode. No `any`, no `@ts-ignore`, no `@ts-expect-error`, no enums.
|
||||
- ESM modules with `.js` suffix in runtime import paths.
|
||||
- Tabs for indentation. Double quotes for strings.
|
||||
- Tests use vitest with `#given .. #when .. #then` descriptions or plain `// given / // when / // then` body comments.
|
||||
|
||||
## Commands
|
||||
|
||||
- `npm install` - install dependencies.
|
||||
- `npm test` - run vitest once.
|
||||
- `npm run typecheck` - strict TypeScript check.
|
||||
- `npm run check` - type check, biome, and build.
|
||||
- `npm pack --dry-run` - release package smoke test.
|
||||
- `node dist/cli.js hook session-start < fixture.json` - smoke-test static rule injection.
|
||||
- `node dist/cli.js hook post-tool-use < fixture.json` - smoke-test dynamic rule injection.
|
||||
|
||||
## Constraints
|
||||
|
||||
- No Bun APIs. Runtime is Node only because Codex launches plugin hooks with Node.
|
||||
- Keep `SessionStart`, `UserPromptSubmit`, and `PostToolUse` hook behavior covered by tests.
|
||||
- Keep Codex file path extraction for reads, edits, `apply_patch`, and shell-style tools covered by tests.
|
||||
- Hook output must use the stable Codex hook JSON contract.
|
||||
- Do not couple this package back to pi, omo, or senpi internal source paths.
|
||||
|
||||
## Don'ts
|
||||
|
||||
- No `git add -A` or `git add .`. Stage only the files you changed.
|
||||
- No `git commit --no-verify`. No force pushes. No history rewriting on shared branches.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Restrict the default `PostToolUse` hook matcher to Codex's canonical `apply_patch` tool name.
|
||||
- Add opt-in `NODE_DEBUG=codex-rules` phase timing logs for `PostToolUse` debugging.
|
||||
- Harden dynamic hook coverage for additional-context JSON output, disabled/static modes, failed tool responses, and duplicate suppression.
|
||||
- Remove redundant apply_patch path scanning and stale tracked-tool constants.
|
||||
- Use portable Codex hook interpolation and add package smoke coverage for hook entrypoints.
|
||||
- Cap recursive rule directory scans and run CI on Windows in addition to Ubuntu and macOS.
|
||||
- Replace the external glob matcher dependency with an internal matcher so clean Codex plugin installs run without `node_modules`.
|
||||
|
||||
## 0.1.0 - 2026-05-15
|
||||
|
||||
- Port `pi-rules` rule loading, matching, formatting, truncation, and deduplication to a Codex plugin.
|
||||
- Add `SessionStart`, `UserPromptSubmit`, and `PostToolUse` hooks for static and file-specific context injection.
|
||||
- Add persistent per-session deduplication under Codex plugin data.
|
||||
- Add Codex-aware path extraction for read, write, edit, multi-edit, `apply_patch`, and shell command payloads.
|
||||
- Add tests, CI, release workflow, marketplace metadata, and local install support.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Yeongyu Kim
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,15 @@
|
||||
codex-rules
|
||||
|
||||
This package implements rule/context loading for Codex plugins.
|
||||
Its behavior is ported from pi-rules in the pi coding-agent extension ecosystem
|
||||
and inspired by oh-my-openagent (omo) at https://github.com/code-yeongyu/oh-my-openagent,
|
||||
including omo's `.omo/rules/` workflow and rules-injector hook architecture.
|
||||
omo is originally licensed under the Sustainable Use License 1.0.
|
||||
|
||||
Yeongyu Kim (https://github.com/code-yeongyu), author of omo, pi-rules, and this
|
||||
package, licenses the source distributed in this repository under the MIT License.
|
||||
If any source was ported from omo or pi-rules, that ported source is re-licensed
|
||||
here under MIT for distribution as a Codex plugin. See LICENSE for terms.
|
||||
|
||||
picomatch is by Jon Schlinkert and contributors (https://github.com/micromatch/picomatch).
|
||||
Distributed under the MIT License.
|
||||
@@ -0,0 +1,124 @@
|
||||
# codex-rules
|
||||
|
||||
Codex plugin that injects local project rule files into model context through lifecycle hooks.
|
||||
|
||||
It ports the `pi-rules` rule injector to Codex:
|
||||
|
||||
- `SessionStart` and `UserPromptSubmit` load static project instructions once per session.
|
||||
- `PostToolUse` watches Codex `apply_patch` by default, then injects matching file-specific rules as additional context.
|
||||
- `PostCompact` clears the per-session injection cache after manual or automatic compaction so relevant rules can be reintroduced into the compacted conversation.
|
||||
- Session-level deduplication prevents the same rule from being repeated after it has been injected.
|
||||
|
||||
`PostToolUse` output is context-only: it emits `hookSpecificOutput.additionalContext` and does not rewrite tool output.
|
||||
|
||||
The runtime has no npm production dependencies, so a clean Codex marketplace copy can run without a follow-up `npm install`.
|
||||
|
||||
## Rule Sources
|
||||
|
||||
Project-level sources:
|
||||
|
||||
- `AGENTS.md`
|
||||
- `CLAUDE.md`
|
||||
- `CONTEXT.md`
|
||||
- `.omo/rules/**/*.md`
|
||||
- `.claude/rules/**/*.md`
|
||||
- `.cursor/rules/**/*.md`
|
||||
- `.github/instructions/**/*.md`
|
||||
- `.github/copilot-instructions.md`
|
||||
|
||||
User-home sources are also supported by the ported engine when available.
|
||||
|
||||
Markdown rule files may use frontmatter such as:
|
||||
|
||||
```md
|
||||
---
|
||||
description: TypeScript defaults
|
||||
globs: ["**/*.ts", "**/*.tsx"]
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
Prefer strict TypeScript and keep runtime imports ESM-compatible.
|
||||
```
|
||||
|
||||
## Install Locally
|
||||
|
||||
```bash
|
||||
bunx lazycodex install
|
||||
```
|
||||
|
||||
The local installer builds the plugin and copies a clean cache entry to:
|
||||
|
||||
```text
|
||||
~/.codex/plugins/cache/sisyphuslabs/omo/0.1.0
|
||||
```
|
||||
|
||||
It also enables:
|
||||
|
||||
```toml
|
||||
[features]
|
||||
plugins = true
|
||||
plugin_hooks = true
|
||||
|
||||
[plugins."omo@sisyphuslabs"]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Use `CODEX_RULES_*` environment variables:
|
||||
|
||||
| Variable | Values | Default |
|
||||
| --- | --- | --- |
|
||||
| `CODEX_RULES_DISABLED` | `1`, `true`, `yes`, `on` | unset |
|
||||
| `CODEX_RULES_MODE` | `both`, `static`, `dynamic`, `off` | `both` |
|
||||
| `CODEX_RULES_MAX_RULE_CHARS` | positive integer | `12000` |
|
||||
| `CODEX_RULES_MAX_RESULT_CHARS` | positive integer | `40000` |
|
||||
| `CODEX_RULES_ENABLED_SOURCES` | comma-separated source names | `auto` |
|
||||
|
||||
For migration from `pi-rules`, equivalent `PI_RULES_*` variables are accepted as fallbacks.
|
||||
|
||||
## Debugging
|
||||
|
||||
Enable hook phase timing with `NODE_DEBUG=codex-rules`:
|
||||
|
||||
```bash
|
||||
NODE_DEBUG=codex-rules node dist/cli.js hook post-tool-use < fixture.json
|
||||
```
|
||||
|
||||
Debug lines go to stderr and hook JSON stays on stdout. The log includes `PostToolUse` phases such as `extract`, `fingerprint`, `load`, `persist`, elapsed `ms`, target counts, pending counts, rule counts, and output bytes. It does not log rule bodies or tool response contents.
|
||||
|
||||
The default `PostToolUse` hook matcher is intentionally strict: it matches only Codex's canonical `apply_patch` hook tool name. Read tools, MCP filesystem tools, shell commands, and Claude-style `Write`/`Edit` aliases are not registered by default.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm test
|
||||
npm run check
|
||||
npm run typecheck
|
||||
npm pack --dry-run
|
||||
```
|
||||
|
||||
Performance smoke test:
|
||||
|
||||
```bash
|
||||
npm run bench
|
||||
```
|
||||
|
||||
Benchmark timings depend on the local machine. Use the relative counters and repeat-output checks when comparing runs.
|
||||
|
||||
Hook smoke test:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
printf '%s\n' '{"session_id":"s","transcript_path":null,"cwd":"/path/to/project","hook_event_name":"SessionStart","model":"gpt-5.5","permission_mode":"default","source":"startup"}' \
|
||||
| PLUGIN_DATA=/tmp/codex-rules-data node dist/cli.js hook session-start
|
||||
```
|
||||
|
||||
## Privacy
|
||||
|
||||
`codex-rules` runs locally. It reads local rule files and Codex hook payloads, writes per-session deduplication state under the Codex plugin data directory, and does not make network requests.
|
||||
|
||||
## License
|
||||
|
||||
MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"style": {
|
||||
"noDefaultExport": "error",
|
||||
"noEnum": "error",
|
||||
"noNonNullAssertion": "error",
|
||||
"useImportType": "error",
|
||||
"useConst": "error",
|
||||
"useNodejsImportProtocol": "off"
|
||||
},
|
||||
"complexity": {
|
||||
"useLiteralKeys": "off"
|
||||
},
|
||||
"suspicious": {
|
||||
"noExplicitAny": "error",
|
||||
"noTsIgnore": "error",
|
||||
"noControlCharactersInRegex": "off",
|
||||
"noEmptyInterface": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"formatWithErrors": false,
|
||||
"indentStyle": "tab",
|
||||
"indentWidth": 3,
|
||||
"lineWidth": 120
|
||||
},
|
||||
"files": {
|
||||
"includes": ["src/**/*.ts", "test/**/*.ts", "vitest.config.ts", "!**/node_modules/**/*", "!**/dist/**/*"]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"includes": ["vitest.config.ts"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"style": {
|
||||
"noDefaultExport": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "@code-yeongyu/codex-rules",
|
||||
"version": "0.1.0",
|
||||
"description": "Codex plugin that injects project rule files into model context through lifecycle hooks.",
|
||||
"type": "module",
|
||||
"packageManager": "npm@11.12.1",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/code-yeongyu/codex-rules",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/code-yeongyu/codex-rules.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/code-yeongyu/codex-rules/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"codex",
|
||||
"codex-plugin",
|
||||
"rules",
|
||||
"hooks",
|
||||
"agents-md",
|
||||
"context-injection",
|
||||
"typescript"
|
||||
],
|
||||
"bin": {
|
||||
"omo-rules": "./dist/cli.js"
|
||||
},
|
||||
"files": [
|
||||
"bundled-rules",
|
||||
"dist",
|
||||
"hooks",
|
||||
"skills",
|
||||
".codex-plugin",
|
||||
"LICENSE",
|
||||
"NOTICE",
|
||||
"README.md",
|
||||
"CHANGELOG.md"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.build.json",
|
||||
"test": "vitest --run",
|
||||
"test:watch": "vitest",
|
||||
"bench": "npm run build --silent && node scripts/bench-codex-rules.mjs",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "biome check .",
|
||||
"lint:fix": "biome check --write .",
|
||||
"check": "tsc --noEmit && biome check . && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"picomatch": "^4.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.4.15",
|
||||
"@types/node": "^25.7.0",
|
||||
"@types/picomatch": "^4.0.0",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^4.1.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowImportingTsExtensions": false,
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["test/**/*"]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"lib": ["ES2022"],
|
||||
"strict": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"esModuleInterop": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"useDefineForClassFields": false,
|
||||
"types": ["node"],
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["src/**/*", "test/**/*"]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: "node",
|
||||
pool: "threads",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user