oh-my-opencode 4.11.0 → 4.12.0
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.
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.mjs +132 -82
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.test.js +48 -0
- package/.agents/skills/opencode-qa/scripts/serve-wake-split-probe.sh +361 -84
- package/.agents/skills/work-with-pr/SKILL.md +19 -5
- package/.opencode/skills/work-with-pr/SKILL.md +19 -5
- package/dist/agents/atlas/agent.d.ts +3 -2
- package/dist/agents/sisyphus/glm-5-2.d.ts +4 -0
- package/dist/agents/sisyphus/index.d.ts +1 -0
- package/dist/agents/sisyphus-agent-config.d.ts +1 -0
- package/dist/agents/sisyphus-junior/agent.d.ts +1 -1
- package/dist/agents/sisyphus-junior/glm-5-2.d.ts +1 -0
- package/dist/agents/sisyphus-junior/index.d.ts +1 -0
- package/dist/agents/types.d.ts +7 -6
- package/dist/cli/index.js +449 -318
- package/dist/cli-node/index.js +449 -318
- package/dist/features/background-agent/parent-wake-flush-runner.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-history-state.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-session-history.d.ts +1 -47
- package/dist/features/background-agent/parent-wake-session-message.d.ts +47 -0
- package/dist/hooks/keyword-detector/ultrawork/glm.d.ts +2 -0
- package/dist/hooks/keyword-detector/ultrawork/index.d.ts +4 -2
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +5 -4
- package/dist/index.js +1185 -87
- package/dist/plugin/tool-execute-before.d.ts +2 -0
- package/dist/plugin-handlers/plugin-components-loader.d.ts +1 -0
- package/dist/skills/init-deep/SKILL.md +21 -26
- package/dist/skills/programming/SKILL.md +25 -121
- package/dist/skills/programming/references/code-smells.md +390 -0
- package/dist/skills/ulw-plan/SKILL.md +2 -1
- package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -2
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -2
- package/dist/tools/delegate-task/sync-session-turns.d.ts +3 -0
- package/dist/tui.js +16 -7
- package/package.json +13 -13
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +22 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +51 -21
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +18 -7
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +9 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +8 -7
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +7 -2
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +2 -1
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +20 -19
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +94 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +33 -0
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/test/package-smoke.test.ts +2 -71
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +26 -104
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +12 -92
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +3 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +157 -234
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +227 -15
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +62 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +34 -3
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/test-support/package-smoke-fixture.ts +158 -0
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +76 -49
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +16 -0
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +17 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/package-lock.json +12 -22
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +1 -1
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +14 -11
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +15 -4
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +37 -0
- package/packages/omo-codex/plugin/skills/ast-grep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/comment-checker/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/debugging/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/frontend/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/git-master/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +21 -26
- package/packages/omo-codex/plugin/skills/init-deep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lsp/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +25 -121
- package/packages/omo-codex/plugin/skills/programming/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/references/code-smells.md +390 -0
- package/packages/omo-codex/plugin/skills/refactor/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/review-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/rules/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/skills/teammode/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/skills/ultraresearch/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/skills/visual-qa/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +34 -33
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +5 -2
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +13 -0
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +14 -6
- package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +7 -3
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +31 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/display-metadata.test.mjs +83 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +30 -19
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +9 -4
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +88 -0
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +240 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +412 -216
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +24 -0
- package/packages/omo-codex/scripts/install-hook-targets.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-local-bun-global-update.test.mjs +63 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +109 -1
- package/packages/omo-codex/scripts/install-local.mjs +1 -0
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +36 -0
- package/packages/shared-skills/skills/init-deep/SKILL.md +21 -26
- package/packages/shared-skills/skills/programming/SKILL.md +25 -121
- package/packages/shared-skills/skills/programming/references/code-smells.md +390 -0
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/hooks/hooks.json +0 -214
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { PluginContext } from "./types";
|
|
2
2
|
import type { CreatedHooks } from "../create-hooks";
|
|
3
|
+
import type { BackgroundManager } from "../features/background-agent";
|
|
3
4
|
export declare function createToolExecuteBeforeHandler(args: {
|
|
4
5
|
ctx: PluginContext;
|
|
5
6
|
hooks: CreatedHooks;
|
|
7
|
+
backgroundManager?: Pick<BackgroundManager, "hasActiveChildTasks" | "hasPendingParentWake">;
|
|
6
8
|
}): (input: {
|
|
7
9
|
tool: string;
|
|
8
10
|
sessionID: string;
|
|
@@ -20,7 +20,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
|
|
|
20
20
|
|
|
21
21
|
1. **Discovery + Analysis** (concurrent)
|
|
22
22
|
- Fire background explore agents immediately
|
|
23
|
-
- Main session: bash structure + LSP
|
|
23
|
+
- Main session: bash structure + LSP/codegraph code map + read existing AGENTS.md
|
|
24
24
|
2. **Score & Decide** - Determine AGENTS.md locations from merged findings
|
|
25
25
|
3. **Generate** - Root first, then subdirs in parallel
|
|
26
26
|
4. **Review** - Deduplicate, trim, validate
|
|
@@ -29,7 +29,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
|
|
|
29
29
|
**TodoWrite ALL phases. Mark in_progress → completed in real-time.**
|
|
30
30
|
```
|
|
31
31
|
TodoWrite([
|
|
32
|
-
{ id: "discovery", content: "Fire explore agents + LSP
|
|
32
|
+
{ id: "discovery", content: "Fire explore agents + LSP/codegraph map + read existing", status: "pending", priority: "high" },
|
|
33
33
|
{ id: "scoring", content: "Score directories, determine locations", status: "pending", priority: "high" },
|
|
34
34
|
{ id: "generate", content: "Generate AGENTS.md files (root + subdirs)", status: "pending", priority: "high" },
|
|
35
35
|
{ id: "review", content: "Deduplicate, validate, trim", status: "pending", priority: "medium" }
|
|
@@ -45,16 +45,16 @@ TodoWrite([
|
|
|
45
45
|
|
|
46
46
|
### Fire Background Explore Agents IMMEDIATELY
|
|
47
47
|
|
|
48
|
-
Don't wait-these run async while main session works.
|
|
48
|
+
Don't wait-these run async while main session works. **Equip every agent with the code graph**: any task touching structure, entry points, dependencies, or hotspots MUST query `codegraph_*` (explore/search/callers/callees/impact) and `lsp_symbols` when present, and ground its claims in that data instead of guessing from conventions. Richer real-graph context per agent = a more accurate project map.
|
|
49
49
|
|
|
50
50
|
```
|
|
51
51
|
// Fire all at once, collect results later
|
|
52
|
-
task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure:
|
|
53
|
-
task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files → REPORT non-standard organization")
|
|
52
|
+
task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure: map real layout via codegraph_explore/codegraph_files → REPORT deviations from standard patterns")
|
|
53
|
+
task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files, trace reach via codegraph_callees + lsp_symbols → REPORT non-standard organization")
|
|
54
54
|
task(subagent_type="explore", load_skills=[], description="Find conventions", run_in_background=true, prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules")
|
|
55
55
|
task(subagent_type="explore", load_skills=[], description="Find anti-patterns", run_in_background=true, prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns")
|
|
56
56
|
task(subagent_type="explore", load_skills=[], description="Explore build/CI", run_in_background=true, prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns")
|
|
57
|
-
task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs
|
|
57
|
+
task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs/structure; codegraph_callers on core modules to see what is covered → REPORT unique conventions")
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
<dynamic-agents>
|
|
@@ -116,24 +116,19 @@ For each existing file found:
|
|
|
116
116
|
|
|
117
117
|
If `--create-new`: Read all existing first (preserve context) → then delete all → regenerate.
|
|
118
118
|
|
|
119
|
-
#### 3. LSP
|
|
120
|
-
```
|
|
121
|
-
LspServers() # Check availability
|
|
119
|
+
#### 3. Code Map - drive LSP AND codegraph (do NOT skip)
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
LspDocumentSymbols(filePath="src/index.ts")
|
|
125
|
-
LspDocumentSymbols(filePath="main.py")
|
|
121
|
+
Highest-signal source for the CODE MAP and the Symbol/Export/Reference scoring rows. Complementary, not alternatives - run BOTH when present, alongside the explore agents.
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
**LSP** - check `lsp_status`; model-facing names are `lsp_status`/`lsp_symbols`/`lsp_find_references`/`lsp_goto_definition` (some harnesses drop the `lsp_` prefix):
|
|
124
|
+
- `lsp_symbols` scope="document" on each entry point -> file outline.
|
|
125
|
+
- `lsp_symbols` scope="workspace", query by kind (class/interface/function) -> symbol inventory.
|
|
126
|
+
- `lsp_find_references` on top exports (line/character from the symbols result) -> reference centrality.
|
|
131
127
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
```
|
|
128
|
+
**codegraph** - when `codegraph_*` tools exist (check `codegraph_status`); a first-class peer to LSP, NOT a last resort:
|
|
129
|
+
- `codegraph_explore` -> overview; `codegraph_callers`/`codegraph_callees`/`codegraph_impact` -> centrality + blast radius for the scoring matrix; `codegraph_search`/`codegraph_files` -> symbol/file inventory.
|
|
135
130
|
|
|
136
|
-
|
|
131
|
+
Only if NEITHER exists: explore agents + the ast-grep skill (`sg`), and mark centrality unmeasured in the CODE MAP.
|
|
137
132
|
|
|
138
133
|
### Collect Background Results
|
|
139
134
|
|
|
@@ -142,7 +137,7 @@ LspFindReferences(filePath="...", line=X, character=Y)
|
|
|
142
137
|
for each background task ID (`bg_...`): background_output(task_id="bg_...")
|
|
143
138
|
```
|
|
144
139
|
|
|
145
|
-
**Merge: bash + LSP + existing + explore findings. Mark "discovery" as completed.**
|
|
140
|
+
**Merge: bash + LSP/codegraph + existing + explore findings. Mark "discovery" as completed.**
|
|
146
141
|
|
|
147
142
|
---
|
|
148
143
|
|
|
@@ -159,9 +154,9 @@ for each background task ID (`bg_...`): background_output(task_id="bg_...")
|
|
|
159
154
|
| Code ratio | 2x | >70% | bash |
|
|
160
155
|
| Unique patterns | 1x | Has own config | explore |
|
|
161
156
|
| Module boundary | 2x | Has index.ts/__init__.py | bash |
|
|
162
|
-
| Symbol density | 2x | >30 symbols | LSP |
|
|
163
|
-
| Export count | 2x | >10 exports | LSP |
|
|
164
|
-
| Reference centrality | 3x | >20 refs | LSP |
|
|
157
|
+
| Symbol density | 2x | >30 symbols | LSP/cg |
|
|
158
|
+
| Export count | 2x | >10 exports | LSP/cg |
|
|
159
|
+
| Reference centrality | 3x | >20 refs | LSP/cg |
|
|
165
160
|
|
|
166
161
|
### Decision Rules
|
|
167
162
|
|
|
@@ -218,7 +213,7 @@ NEVER use Write to overwrite an existing file. ALWAYS check existence first via
|
|
|
218
213
|
|------|----------|-------|
|
|
219
214
|
|
|
220
215
|
## CODE MAP
|
|
221
|
-
{From LSP - skip if
|
|
216
|
+
{From LSP/codegraph - skip only if neither exists or project <10 files}
|
|
222
217
|
|
|
223
218
|
| Symbol | Type | Location | Refs | Role |
|
|
224
219
|
|--------|------|----------|------|------|
|
|
@@ -301,7 +296,7 @@ Hierarchy:
|
|
|
301
296
|
## Anti-Patterns
|
|
302
297
|
|
|
303
298
|
- **Static agent count**: MUST vary agents based on project size/depth
|
|
304
|
-
- **Sequential execution**: MUST parallel (explore + LSP concurrent)
|
|
299
|
+
- **Sequential execution**: MUST parallel (explore + LSP + codegraph concurrent)
|
|
305
300
|
- **Ignoring existing**: ALWAYS read existing first, even with --create-new
|
|
306
301
|
- **Over-documenting**: Not every dir needs AGENTS.md
|
|
307
302
|
- **Redundancy**: Child never repeats parent
|
|
@@ -182,134 +182,35 @@ A `tsconfig.json` with `"strict": true` alone is **not** strict. The reference e
|
|
|
182
182
|
|
|
183
183
|
---
|
|
184
184
|
|
|
185
|
-
##
|
|
185
|
+
## CODE SMELLS — AUTOMATIC REVIEW TRIGGERS
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
Most smells below are design review triggers: STOP, re-examine the code, and either fix the smell or justify carrying it with a SPECIFIC reason. **The 250 pure LOC ceiling is stricter: >250 is a DEFECT. Refactor before adding lines except for rare SIZE_OK or pure-data-table exceptions.**
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
Full rationale, measurement methods, workaround detection, and split examples: **[`references/code-smells.md`](references/code-smells.md)**.
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
- Multiple cohesive units got merged "to save a file".
|
|
193
|
-
- Re-exports, barrels, and orchestrators got fused into pure-logic units.
|
|
194
|
-
- Every future reader pays a tax to find what they need.
|
|
191
|
+
### Smell 1 — File exceeds 250 pure LOC
|
|
195
192
|
|
|
196
|
-
|
|
193
|
+
A source file past 250 non-blank, non-comment lines has outgrown a single reviewer's working memory. The module is almost certainly doing more than one thing. Measure: `awk '!/^[[:space:]]*$/ && !/^[[:space:]]*(\/\/|#|--)/' <file> | wc -l`.
|
|
197
194
|
|
|
198
|
-
|
|
195
|
+
**When detected:** Name what the file owns in one short noun phrase. If the answer needs "and", the file needs splitting. Load `/refactor` and split by responsibility. If the file genuinely cannot be split (generated parser, indivisible state machine), mark with `// allow: SIZE_OK — <reason>`.
|
|
199
196
|
|
|
200
|
-
###
|
|
197
|
+
### Smell 2 — Function with more than 3 parameters
|
|
201
198
|
|
|
202
|
-
|
|
203
|
-
# Quick (line-comment + blank exclusion - good enough for Python, Rust, TypeScript):
|
|
204
|
-
awk '!/^[[:space:]]*$/ && !/^[[:space:]]*(\/\/|#|--)/' <file> | wc -l
|
|
205
|
-
|
|
206
|
-
# Authoritative (handles block comments correctly):
|
|
207
|
-
cloc --by-file <file> # the "code" column is the number that matters
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Required behavior
|
|
211
|
-
|
|
212
|
-
**Creating a file that will exceed 250 pure LOC.** STOP. Split it **before the first commit**. Carve by responsibility (single-responsibility principle), one cohesive unit per file. Use a barrel (`__init__.py`, `mod.rs`, `index.ts`) for re-exports ONLY. **Never** for logic.
|
|
213
|
-
|
|
214
|
-
**Editing a file that already exceeds 250 pure LOC and your edit adds lines.** STOP. Refactor the unit you are touching into its own file BEFORE adding the new lines. The split is part of THIS task, not a follow-up someone will never do.
|
|
215
|
-
|
|
216
|
-
**Reading a file that exceeds 250 pure LOC while implementing a feature.** Surface the smell explicitly in your reply, propose a concrete split (which functions go where, in 1-2 lines each), and ask the user whether to split now or carry the smell into the feature work. Do not silently keep going.
|
|
217
|
-
|
|
218
|
-
### Forbidden escapes
|
|
219
|
-
|
|
220
|
-
- Counting comments and blank lines toward the budget. **Pure LOC means code lines.** Period.
|
|
221
|
-
- Splitting by token count (`foo_1.py`, `module_part_A.rs`, `service-2.ts`). **REJECT.** Split by what each file DOES. Name each file after the concept it owns.
|
|
222
|
-
- Catch-all dump files: `utils.py`, `helpers.ts`, `lib.rs` (as a logic dump), `common.py`, `shared.ts`. **REJECT.** These just relocate the smell.
|
|
223
|
-
- "It's generated, so it's fine." Only true if the file lives in `dist/`, `target/`, `__generated__/`, or wherever the build authoritatively rewrites. Hand-edited "I will regenerate it later" files do NOT qualify.
|
|
224
|
-
- "It's a test file with many cases." Split by SUT or by behavior cluster. One file per cohesive `describe` group.
|
|
225
|
-
- "230 pure LOC, close enough." A 230-LOC file about to grow is already over the line. Split now. **Do not race to the ceiling.**
|
|
226
|
-
|
|
227
|
-
### Acceptable exceptions (rare, require justification)
|
|
228
|
-
|
|
229
|
-
A file may legitimately exceed 250 pure LOC if **and only if** it is:
|
|
230
|
-
|
|
231
|
-
- A **truly indivisible single-responsibility unit** (e.g., a generated parser table, a state machine whose states share a single closure, a `derive` macro implementation). Mark the first 5 lines with a comment such as `# noqa: SIZE_OK - generated parser table, 612 states share branch tables` (Python) / `// allow: SIZE_OK - state machine, removing any state breaks the transition matrix` (Rust/TS), and explain WHY no split is possible.
|
|
232
|
-
- A **pure data table** (translation strings, error code lookup, brand color palette). Tables of data are not logic.
|
|
233
|
-
|
|
234
|
-
**`# noqa: SIZE_OK` without a justifying comment is itself slop** and must be rejected by the next person to touch the file.
|
|
235
|
-
|
|
236
|
-
### Concrete split examples
|
|
199
|
+
More than 3 arguments signals the function is doing too much, or that related parameters belong in a typed struct. **Workarounds count as the same smell** — passing `dict`/`Record<string, unknown>`/`map[string]any`/`**kwargs`/`...args` to smuggle parameters through one argument, or a throwaway "config" object with 6+ fields that exists solely to wrap what would otherwise be positional args (genuine reusable domain types like `HttpClientConfig` are fine).
|
|
237
200
|
|
|
238
|
-
|
|
201
|
+
**When detected:** Group related parameters into a typed value object with a domain name. If 4+ independent inputs are genuinely required, the justification must be SPECIFIC. See [`references/code-smells.md` Smell 2](references/code-smells.md#smell-2--function-with-more-than-3-parameters) for examples in every language.
|
|
239
202
|
|
|
240
|
-
|
|
241
|
-
# user_service.py - DOES TOO MUCH
|
|
242
|
-
class UserRepository: ... # 90 LOC of SQLAlchemy
|
|
243
|
-
class UserValidator: ... # 60 LOC of Pydantic + business rules
|
|
244
|
-
class PasswordHasher: ... # 40 LOC of bcrypt wrapper
|
|
245
|
-
class EmailSender: ... # 50 LOC of httpx2 client
|
|
246
|
-
class UserService: ... # 130 LOC orchestrating the four above
|
|
247
|
-
def _build_query(...): ... # 25 LOC helper
|
|
248
|
-
def _format_email(...): ... # 17 LOC helper
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
#### Python - AFTER (split by responsibility)
|
|
252
|
-
|
|
253
|
-
```
|
|
254
|
-
src/myapp/users/
|
|
255
|
-
├── __init__.py # barrel: re-exports UserService only (5 LOC)
|
|
256
|
-
├── repository.py # UserRepository (~95 LOC)
|
|
257
|
-
├── validator.py # UserValidator (~65 LOC)
|
|
258
|
-
├── password.py # PasswordHasher (~45 LOC)
|
|
259
|
-
├── notifier.py # EmailSender (renamed - the role, not the verb)
|
|
260
|
-
├── service.py # UserService (orchestrator) (~135 LOC)
|
|
261
|
-
└── _queries.py # _build_query (private) (~30 LOC)
|
|
262
|
-
```
|
|
203
|
+
### Smell 3 — Redundant verification after a destructive action
|
|
263
204
|
|
|
264
|
-
|
|
205
|
+
Performing a delete/remove/clear/drop and then immediately querying to "confirm" the thing is gone. **The operation's contract IS the verification.** Re-checking is AI-generated defensive bloat that wastes cycles and teaches the reader the operation is unreliable — which it is not. Same smell: calling a setter then getting to "confirm", writing a file then reading it back, inserting a row then SELECT-ing it, pushing to an array then checking `.length`.
|
|
265
206
|
|
|
266
|
-
|
|
207
|
+
**When detected:** Delete the verification code. Trust the operation's contract. If the operation can genuinely fail silently, fix the operation — do not paper over it with a post-check. See [`references/code-smells.md` Smell 3](references/code-smells.md#smell-3--redundant-verification-after-a-destructive-action) for examples.
|
|
267
208
|
|
|
268
|
-
|
|
269
|
-
// auth.rs - DOES TOO MUCH
|
|
270
|
-
pub struct Session { ... } // 40 LOC
|
|
271
|
-
impl Session { ... } // 90 LOC of methods
|
|
272
|
-
pub struct TokenIssuer { ... } // 30 LOC
|
|
273
|
-
impl TokenIssuer { ... } // 70 LOC
|
|
274
|
-
pub struct RateLimiter { ... } // 50 LOC
|
|
275
|
-
impl RateLimiter { ... } // 70 LOC
|
|
276
|
-
fn parse_authorization_header(...) { ... } // 30 LOC
|
|
277
|
-
```
|
|
209
|
+
### Smell 4 — Negative-form names and conditions
|
|
278
210
|
|
|
279
|
-
|
|
211
|
+
Naming variables, functions, or flags by the **absence** of a quality (`isNotValid`, `noErrors`, `cannotProceed`, `DisableLogging`) instead of its **presence** (`isValid`, `isClean`, `canProceed`, `LoggingEnabled`). Every negation forces the reader to invert mentally; two negations (`if !isNotReady`) become a logic puzzle nobody reviews confidently.
|
|
280
212
|
|
|
281
|
-
|
|
282
|
-
src/auth/
|
|
283
|
-
├── mod.rs # re-exports Session, TokenIssuer, RateLimiter (8 LOC)
|
|
284
|
-
├── session.rs # Session + impl (~130 LOC)
|
|
285
|
-
├── token.rs # TokenIssuer + impl (~100 LOC)
|
|
286
|
-
├── rate_limit.rs # RateLimiter + impl (~120 LOC)
|
|
287
|
-
└── header.rs # parse_authorization_header (~35 LOC)
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
#### TypeScript - BEFORE (`api/orders.ts`, 510 pure LOC)
|
|
291
|
-
|
|
292
|
-
```typescript
|
|
293
|
-
// api/orders.ts - DOES TOO MUCH
|
|
294
|
-
export const OrderSchema = z.object({ ... }) // 30 LOC
|
|
295
|
-
type Order = z.infer<typeof OrderSchema>
|
|
296
|
-
export class OrderRepository { ... } // 110 LOC
|
|
297
|
-
export class PricingEngine { ... } // 130 LOC
|
|
298
|
-
export class TaxCalculator { ... } // 90 LOC
|
|
299
|
-
export class OrderService { ... } // 150 LOC
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
#### TypeScript - AFTER
|
|
303
|
-
|
|
304
|
-
```
|
|
305
|
-
src/orders/
|
|
306
|
-
├── index.ts # barrel (6 LOC)
|
|
307
|
-
├── schema.ts # OrderSchema + Order type (~35 LOC)
|
|
308
|
-
├── repository.ts # OrderRepository (~115 LOC)
|
|
309
|
-
├── pricing.ts # PricingEngine (~135 LOC)
|
|
310
|
-
├── tax.ts # TaxCalculator (~95 LOC)
|
|
311
|
-
└── service.ts # OrderService (orchestrator) (~155 LOC)
|
|
312
|
-
```
|
|
213
|
+
**When detected:** Rename to the positive form and invert the branch logic. Negation IS appropriate in guard clauses (`if !authorized { return }`) and filters (`items.filter(|x| !x.is_expired())`) — the negative form is the intent there. See [`references/code-smells.md` Smell 4](references/code-smells.md#smell-4--negative-form-names-and-conditions) for the full naming table and examples.
|
|
313
214
|
|
|
314
215
|
---
|
|
315
216
|
|
|
@@ -341,8 +242,8 @@ bun run scripts/typescript/check-no-excuse-rules.ts <changed paths>
|
|
|
341
242
|
| Pure LOC | Verdict | Required action |
|
|
342
243
|
|---|---|---|
|
|
343
244
|
| ≤ 200 | Healthy | continue |
|
|
344
|
-
| 200 - 250 | **Warning band**
|
|
345
|
-
| > 250 | **DEFECT**
|
|
245
|
+
| 200 - 250 | **Warning band** | State that fact and propose a split if the next edit will add lines. |
|
|
246
|
+
| > 250 | **DEFECT** | Do NOT commit new lines to this file. Refactor now: split the touched unit before adding lines, except for rare SIZE_OK or pure-data-table exceptions. |
|
|
346
247
|
|
|
347
248
|
### Step 3 — architectural self-review (always, even at 80 LOC)
|
|
348
249
|
|
|
@@ -355,15 +256,18 @@ After every code-writing session, answer these out loud (in your reply) before d
|
|
|
355
256
|
5. **Defensive layer?** Any null check, try/except, or `isinstance` guarding a value the type system already proves? If yes, delete.
|
|
356
257
|
6. **Helpers for one-off?** Any function, class, or trait introduced for a single caller that will never get a second caller? If yes, inline.
|
|
357
258
|
7. **Tests?** Is the behavior I just introduced locked by a test that would fail if I revert this commit?
|
|
259
|
+
8. **Parameter bloat?** Any function I wrote or modified that takes more than 3 parameters — or smuggles them through a dict/kwargs/`...args`/throwaway options object? If yes, group related params into a typed value object. See [Smell 2](references/code-smells.md#smell-2--function-with-more-than-3-parameters).
|
|
260
|
+
9. **Redundant verification?** Did I perform a destructive action (delete, remove, clear) and then immediately re-query to "confirm" it worked? Did I call a setter then a getter to "verify"? If yes, delete the verification — the operation's contract IS the proof. See [Smell 3](references/code-smells.md#smell-3--redundant-verification-after-a-destructive-action).
|
|
261
|
+
10. **Negative naming?** Any variable, function, or flag named by the absence of a quality (`isNotValid`, `noErrors`, `DisableX`) when a positive name (`isValid`, `isClean`, `EnableX`) would work? If yes, rename to positive form and invert the branch. See [Smell 4](references/code-smells.md#smell-4--negative-form-names-and-conditions).
|
|
358
262
|
|
|
359
263
|
**If any answer fails, fix it before declaring done.** This loop is the difference between "the code compiles" and "the code is correct."
|
|
360
264
|
|
|
361
265
|
### Step 4 — if you need to refactor right now, invoke the right skill
|
|
362
266
|
|
|
363
|
-
-
|
|
364
|
-
- You inherited a branch with AI-generated patterns (broad `except`, redundant null checks, vague TODOs, oversized modules, dead helpers): **load the `remove-ai-slops` skill** to do a categorized branch-scope cleanup with regression tests pinned first.
|
|
267
|
+
- Any code smell from the [CODE SMELLS section](#code-smells--automatic-review-triggers) fired (250+ LOC, >3 params, redundant verification, negative naming), or step 3 surfaced more than two issues: **load the `refactor` skill** and execute its safe-refactor protocol (codemap, plan, LSP-driven edits, test after each step). Do not improvise a refactor under time pressure — the refactor skill exists precisely so you do not corrupt behavior while reshaping structure.
|
|
268
|
+
- You inherited a branch with AI-generated patterns (broad `except`, redundant null checks, vague TODOs, oversized modules, dead helpers, redundant post-action verification): **load the `remove-ai-slops` skill** to do a categorized branch-scope cleanup with regression tests pinned first.
|
|
365
269
|
|
|
366
|
-
These two skills are not optional cosmetics. They are the recovery path for the
|
|
270
|
+
These two skills are not optional cosmetics. They are the recovery path for the smells this loop is designed to catch.
|
|
367
271
|
|
|
368
272
|
---
|
|
369
273
|
|
|
@@ -371,8 +275,8 @@ These two skills are not optional cosmetics. They are the recovery path for the
|
|
|
371
275
|
|
|
372
276
|
| Trigger | Skill to load | Why |
|
|
373
277
|
|---|---|---|
|
|
374
|
-
|
|
|
375
|
-
| Recent branch contains AI-authored
|
|
278
|
+
| Any [code smell](#code-smells--automatic-review-triggers) fires (250+ LOC, >3 params, redundant verification), OR the post-write loop surfaces 2+ issues, OR the user says "reshape this", "extract this", "clean this up" | `refactor` | Safe codemap-driven multi-step refactor with LSP + tests after each step. Never improvise a structural change. |
|
|
279
|
+
| Recent branch contains AI-authored patterns (broad except, dead helpers, vague comments, oversized files, redundant post-action verification), OR the user says "remove slop", "clean AI code", "deslop" | `remove-ai-slops` | Tests pinned FIRST, then categorized parallel cleanup, then quality gates. Behavior-preserving. |
|
|
376
280
|
| Rust code touches `unsafe`, `*mut`, `*const`, `MaybeUninit`, FFI, `unsafe impl Send/Sync`, or a custom lock-free primitive | `references/rust-ub/` | Full UB taxonomy + Miri strictness escalation. Every `unsafe` block must survive Miri Level 3 (strict provenance + symbolic alignment + preemption) before it ships. |
|
|
377
281
|
|
|
378
282
|
---
|