code-search-cli 0.2.0__tar.gz → 0.3.0__tar.gz

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 (64) hide show
  1. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/PKG-INFO +62 -15
  2. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/README.md +60 -13
  3. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/pyproject.toml +2 -2
  4. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/scripts/e2e_smoke.py +49 -2
  5. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/cli.py +42 -9
  6. code_search_cli-0.3.0/src/code_retrieval/installer.py +468 -0
  7. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_search_cli.egg-info/PKG-INFO +62 -15
  8. code_search_cli-0.3.0/tests/test_installer.py +394 -0
  9. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/uv.lock +1 -1
  10. code_search_cli-0.2.0/src/code_retrieval/installer.py +0 -65
  11. code_search_cli-0.2.0/tests/test_installer.py +0 -68
  12. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/.gitignore +0 -0
  13. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/LICENSE +0 -0
  14. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/MANIFEST.in +0 -0
  15. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/NOTICE +0 -0
  16. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/README.md +0 -0
  17. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/README.md +0 -0
  18. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/RESULTS.md +0 -0
  19. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/java-lifecycle/PublisherNotifier.java +0 -0
  20. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/java-lifecycle/ReceiverUtil.java +0 -0
  21. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/java-lifecycle/StartupService.java +0 -0
  22. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/python/settings.py +0 -0
  23. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/evidence-showcase/typescript/settings.ts +0 -0
  24. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/multilingual-30/README.md +0 -0
  25. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/multilingual-30/RESULTS.json +0 -0
  26. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/multilingual-30/TASK_IDS.json +0 -0
  27. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/multilingual-30/prepare_manifest.py +0 -0
  28. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/multilingual-30/prepare_snapshots.py +0 -0
  29. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/multilingual-30/run_baselines.py +0 -0
  30. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/render_charts.py +0 -0
  31. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/shared-java/README.md +0 -0
  32. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/shared-java/RESULTS.json +0 -0
  33. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/shared-java/crg_worker.py +0 -0
  34. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/benchmarks/shared-java/run_benchmark.py +0 -0
  35. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/scripts/benchmark_tasks.py +0 -0
  36. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/scripts/compare_retrievers.py +0 -0
  37. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/scripts/evaluate_benchmark.py +0 -0
  38. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/scripts/evaluate_models.py +0 -0
  39. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/scripts/showcase_evidence.py +0 -0
  40. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/setup.cfg +0 -0
  41. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/__init__.py +0 -0
  42. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/__main__.py +0 -0
  43. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/engine.py +0 -0
  44. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/index_store.py +0 -0
  45. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/models.py +0 -0
  46. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/query.py +0 -0
  47. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/repository.py +0 -0
  48. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/resources/code-search/SKILL.md +0 -0
  49. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/resources/code-search/agents/openai.yaml +0 -0
  50. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_retrieval/structure.py +0 -0
  51. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_search_cli.egg-info/SOURCES.txt +0 -0
  52. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_search_cli.egg-info/dependency_links.txt +0 -0
  53. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_search_cli.egg-info/entry_points.txt +0 -0
  54. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/src/code_search_cli.egg-info/top_level.txt +0 -0
  55. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_benchmark_scripts.py +0 -0
  56. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_cli.py +0 -0
  57. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_engine.py +0 -0
  58. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_golden_output.py +0 -0
  59. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_index_store.py +0 -0
  60. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_query.py +0 -0
  61. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_release_hygiene.py +0 -0
  62. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_repository.py +0 -0
  63. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_showcase_evidence.py +0 -0
  64. {code_search_cli-0.2.0 → code_search_cli-0.3.0}/tests/test_structure.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-search-cli
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Task-aware code search with compact, auditable evidence for coding agents
5
5
  Author: Code Search contributors
6
6
  License-Expression: Apache-2.0
@@ -9,7 +9,7 @@ Project-URL: Documentation, https://code-search.quguai.cc/
9
9
  Project-URL: Repository, https://github.com/quguai/code-search
10
10
  Project-URL: Issues, https://github.com/quguai/code-search/issues
11
11
  Project-URL: Changelog, https://github.com/quguai/code-search/releases
12
- Keywords: code-search,code-retrieval,coding-agents,cli,codex
12
+ Keywords: code-search,code-retrieval,coding-agents,agent-skills,cli,codex
13
13
  Classifier: Development Status :: 3 - Alpha
14
14
  Classifier: Environment :: Console
15
15
  Classifier: Intended Audience :: Developers
@@ -39,7 +39,7 @@ Dynamic: license-file
39
39
  <a href="https://pypi.org/project/code-search-cli/"><img alt="PyPI" src="https://img.shields.io/pypi/v/code-search-cli?style=flat-square" /></a>
40
40
  <a href="https://github.com/quguai/code-search/blob/main/LICENSE"><img alt="Apache-2.0 license" src="https://img.shields.io/github/license/quguai/code-search?style=flat-square" /></a>
41
41
  <img alt="Python 3.11+" src="https://img.shields.io/badge/Python-3.11%2B-3776AB?style=flat-square&amp;logo=python&amp;logoColor=white" />
42
- <img alt="Codex skill included" src="https://img.shields.io/badge/Codex-skill_included-5B47D6?style=flat-square" />
42
+ <img alt="Agent Skill installers for seven agents" src="https://img.shields.io/badge/Agent_Skills-7_targets-5B47D6?style=flat-square" />
43
43
  <img alt="Experimental status" src="https://img.shields.io/badge/status-experimental-D97706?style=flat-square" />
44
44
  </p>
45
45
 
@@ -91,15 +91,19 @@ index inside it. It incrementally maintains a per-user SQLite index under the op
91
91
  directory, honors Git ignore rules for working trees, and uses `code-search clean` to remove the
92
92
  cached source snapshot and derived metadata.
93
93
 
94
- ### Optional Codex integration
94
+ ### Optional agent integration
95
95
 
96
96
  ```bash
97
- code-search install
97
+ code-search install # Codex remains the default
98
+ code-search install --target cursor # Or select one target explicitly
98
99
  ```
99
100
 
100
- This installs the bundled `code-search` skill into Codex. Restart Codex so it can discover the
101
- skill. The installer is idempotent and refuses to overwrite a locally modified skill unless
102
- `--force` is supplied.
101
+ The bundled `code-search` Agent Skill can be installed for Codex, Claude Code, Cursor, Gemini CLI,
102
+ OpenCode, GitHub Copilot, or Kiro. Installation is user-level and idempotent. It tracks hashes of
103
+ the files it installed, so an untouched older release can upgrade safely while a locally modified
104
+ skill is still protected unless `--force` is supplied. Add `--dry-run` to preview the operation.
105
+ The CLI remains the primary interface; installing the skill adds neither an MCP server nor a runtime
106
+ model.
103
107
 
104
108
  ### Why there is no model underneath
105
109
 
@@ -125,7 +129,10 @@ versioned comparison methods; they are not Code Search runtime dependencies.
125
129
  default path.
126
130
  - Compact exact-symbol windows across all indexed source formats when the whole task is an
127
131
  identifier or qualified name.
128
- - A bundled Codex skill that teaches the agent when to retrieve, expand, or fall back to exact `rg`.
132
+ - A bundled Agent Skill, with user-level filesystem installers for Codex, Claude Code, Cursor,
133
+ Gemini CLI, OpenCode, GitHub Copilot, and Kiro, that teaches the agent when to retrieve, expand,
134
+ or fall back to exact `rg`. Their paths, dry-run behavior, idempotence, safe upgrades, and
135
+ file-protection behavior have automated coverage.
129
136
 
130
137
  ## Task evidence beyond ranked matches
131
138
 
@@ -185,13 +192,52 @@ code-search expand \
185
192
  --relation enclosing
186
193
  ```
187
194
 
188
- Manage the Codex skill:
195
+ Manage the optional Agent Skill:
189
196
 
190
197
  ```bash
191
- code-search install
192
- code-search uninstall
198
+ code-search install # Codex
199
+ code-search install --target claude-code
200
+ code-search install --target cursor
201
+ code-search install --target gemini
202
+ code-search install --target opencode
203
+ code-search install --target github-copilot
204
+ code-search install --target kiro
205
+ code-search install --target detected # Best-effort convenience selector
206
+ code-search install --target detected --dry-run # Preview without writing
207
+ code-search uninstall --target cursor
208
+ code-search uninstall --target detected
193
209
  ```
194
210
 
211
+ The installer writes only managed Skill files and its hash manifest inside the selected agent's
212
+ user configuration:
213
+
214
+ | `--target` | User-level destination |
215
+ |---|---|
216
+ | `codex` | `$CODEX_HOME/skills/code-search/` when set; otherwise `~/.agents/skills/code-search/` |
217
+ | `claude-code` | `$CLAUDE_CONFIG_DIR/skills/code-search/` when set; otherwise `~/.claude/skills/code-search/` |
218
+ | `cursor` | `~/.cursor/skills/code-search/` |
219
+ | `gemini` | `$GEMINI_CLI_HOME/.gemini/skills/code-search/` when set; otherwise `~/.gemini/skills/code-search/` |
220
+ | `opencode` | `$OPENCODE_CONFIG_DIR/skills/code-search/` when set; otherwise `${XDG_CONFIG_HOME:-~/.config}/opencode/skills/code-search/` |
221
+ | `github-copilot` | `$COPILOT_HOME/skills/code-search/` when set; otherwise `~/.copilot/skills/code-search/` |
222
+ | `kiro` | `~/.kiro/skills/code-search/` |
223
+
224
+ Agent-specific environment overrides must be absolute paths; a relative `XDG_CONFIG_HOME` is ignored
225
+ as required by the XDG base-directory specification. An existing legacy Codex installation under
226
+ `~/.codex/skills/code-search/` is updated and removed in place instead of being silently migrated.
227
+
228
+ `detected` is a best-effort convenience selector based on known commands, configuration directories,
229
+ environment overrides, and an already-installed target. It does not launch a client or verify that
230
+ the client can load the skill. Cursor detection deliberately relies on `~/.cursor` rather than the
231
+ ambiguous `agent` executable name. Because some clients also scan another client's compatibility
232
+ directories, prefer an explicit target and use one if the same skill appears more than once.
233
+
234
+ Every selected destination is preflighted before writing or removing files. A small hidden manifest
235
+ records hashes of the managed files; it is installer metadata, not another instruction loaded by the
236
+ agent. This lets an untouched older installation upgrade without treating it as a user edit.
237
+ Uninstall removes only managed files whose content is still recognized and leaves extra user files
238
+ in place. Use `--force` only when you intentionally want to replace or remove a modified managed
239
+ file. `--dry-run` performs the same checks and reports the planned action without changing files.
240
+
195
241
  Prewarm, inspect, or remove the per-repository index:
196
242
 
197
243
  ```bash
@@ -211,7 +257,7 @@ The repository publishes two recorded development comparisons. Both measure
211
257
  scores must not be merged into one leaderboard. The shared Java runner reproduces all six methods;
212
258
  the multilingual public runner currently reproduces BM25, Probe, and ripgrep, while the other three
213
259
  rows retain their recorded implementation identities and per-task output. The Code Search rows
214
- describe the source revisions recorded by each benchmark, not a new measurement of version 0.2.0.
260
+ describe the source revisions recorded by each benchmark, not a new measurement of the current release.
215
261
 
216
262
  ### Shared Java comparison
217
263
 
@@ -329,7 +375,8 @@ validation remain future work.
329
375
  executable patch tests and repeated model runs.
330
376
  - **P1, retrieval quality:** close the long-query ranking gaps surfaced by the multilingual
331
377
  diagnostic, and add stronger AST/symbol parsers.
332
- - **P1, onboarding breadth:** add safe CLI/skill installers for more coding agents. Consider MCP only
378
+ - **P1, onboarding validation:** expand beyond the seven current user-level Agent Skill destinations
379
+ only when another integration has a real discovery path and automated coverage. Consider MCP only
333
380
  if a resident index or structured tool discovery provides a measured benefit over CLI invocation.
334
381
  - **P2, distribution:** ship signed standalone binaries.
335
382
 
@@ -338,7 +385,7 @@ validation remain future work.
338
385
  This is a testable experimental MVP, not a production release. The public development benchmark
339
386
  measures retrieval, while the deterministic fixtures and tests cover output behavior and package
340
387
  quality. None of them proves held-out retrieval superiority or executable patch success. The
341
- implementation and bundled Codex skill are independently designed around the task-evidence workflow.
388
+ implementation and bundled Agent Skill are independently designed around the task-evidence workflow.
342
389
 
343
390
  ## License
344
391
 
@@ -15,7 +15,7 @@
15
15
  <a href="https://pypi.org/project/code-search-cli/"><img alt="PyPI" src="https://img.shields.io/pypi/v/code-search-cli?style=flat-square" /></a>
16
16
  <a href="https://github.com/quguai/code-search/blob/main/LICENSE"><img alt="Apache-2.0 license" src="https://img.shields.io/github/license/quguai/code-search?style=flat-square" /></a>
17
17
  <img alt="Python 3.11+" src="https://img.shields.io/badge/Python-3.11%2B-3776AB?style=flat-square&amp;logo=python&amp;logoColor=white" />
18
- <img alt="Codex skill included" src="https://img.shields.io/badge/Codex-skill_included-5B47D6?style=flat-square" />
18
+ <img alt="Agent Skill installers for seven agents" src="https://img.shields.io/badge/Agent_Skills-7_targets-5B47D6?style=flat-square" />
19
19
  <img alt="Experimental status" src="https://img.shields.io/badge/status-experimental-D97706?style=flat-square" />
20
20
  </p>
21
21
 
@@ -67,15 +67,19 @@ index inside it. It incrementally maintains a per-user SQLite index under the op
67
67
  directory, honors Git ignore rules for working trees, and uses `code-search clean` to remove the
68
68
  cached source snapshot and derived metadata.
69
69
 
70
- ### Optional Codex integration
70
+ ### Optional agent integration
71
71
 
72
72
  ```bash
73
- code-search install
73
+ code-search install # Codex remains the default
74
+ code-search install --target cursor # Or select one target explicitly
74
75
  ```
75
76
 
76
- This installs the bundled `code-search` skill into Codex. Restart Codex so it can discover the
77
- skill. The installer is idempotent and refuses to overwrite a locally modified skill unless
78
- `--force` is supplied.
77
+ The bundled `code-search` Agent Skill can be installed for Codex, Claude Code, Cursor, Gemini CLI,
78
+ OpenCode, GitHub Copilot, or Kiro. Installation is user-level and idempotent. It tracks hashes of
79
+ the files it installed, so an untouched older release can upgrade safely while a locally modified
80
+ skill is still protected unless `--force` is supplied. Add `--dry-run` to preview the operation.
81
+ The CLI remains the primary interface; installing the skill adds neither an MCP server nor a runtime
82
+ model.
79
83
 
80
84
  ### Why there is no model underneath
81
85
 
@@ -101,7 +105,10 @@ versioned comparison methods; they are not Code Search runtime dependencies.
101
105
  default path.
102
106
  - Compact exact-symbol windows across all indexed source formats when the whole task is an
103
107
  identifier or qualified name.
104
- - A bundled Codex skill that teaches the agent when to retrieve, expand, or fall back to exact `rg`.
108
+ - A bundled Agent Skill, with user-level filesystem installers for Codex, Claude Code, Cursor,
109
+ Gemini CLI, OpenCode, GitHub Copilot, and Kiro, that teaches the agent when to retrieve, expand,
110
+ or fall back to exact `rg`. Their paths, dry-run behavior, idempotence, safe upgrades, and
111
+ file-protection behavior have automated coverage.
105
112
 
106
113
  ## Task evidence beyond ranked matches
107
114
 
@@ -161,13 +168,52 @@ code-search expand \
161
168
  --relation enclosing
162
169
  ```
163
170
 
164
- Manage the Codex skill:
171
+ Manage the optional Agent Skill:
165
172
 
166
173
  ```bash
167
- code-search install
168
- code-search uninstall
174
+ code-search install # Codex
175
+ code-search install --target claude-code
176
+ code-search install --target cursor
177
+ code-search install --target gemini
178
+ code-search install --target opencode
179
+ code-search install --target github-copilot
180
+ code-search install --target kiro
181
+ code-search install --target detected # Best-effort convenience selector
182
+ code-search install --target detected --dry-run # Preview without writing
183
+ code-search uninstall --target cursor
184
+ code-search uninstall --target detected
169
185
  ```
170
186
 
187
+ The installer writes only managed Skill files and its hash manifest inside the selected agent's
188
+ user configuration:
189
+
190
+ | `--target` | User-level destination |
191
+ |---|---|
192
+ | `codex` | `$CODEX_HOME/skills/code-search/` when set; otherwise `~/.agents/skills/code-search/` |
193
+ | `claude-code` | `$CLAUDE_CONFIG_DIR/skills/code-search/` when set; otherwise `~/.claude/skills/code-search/` |
194
+ | `cursor` | `~/.cursor/skills/code-search/` |
195
+ | `gemini` | `$GEMINI_CLI_HOME/.gemini/skills/code-search/` when set; otherwise `~/.gemini/skills/code-search/` |
196
+ | `opencode` | `$OPENCODE_CONFIG_DIR/skills/code-search/` when set; otherwise `${XDG_CONFIG_HOME:-~/.config}/opencode/skills/code-search/` |
197
+ | `github-copilot` | `$COPILOT_HOME/skills/code-search/` when set; otherwise `~/.copilot/skills/code-search/` |
198
+ | `kiro` | `~/.kiro/skills/code-search/` |
199
+
200
+ Agent-specific environment overrides must be absolute paths; a relative `XDG_CONFIG_HOME` is ignored
201
+ as required by the XDG base-directory specification. An existing legacy Codex installation under
202
+ `~/.codex/skills/code-search/` is updated and removed in place instead of being silently migrated.
203
+
204
+ `detected` is a best-effort convenience selector based on known commands, configuration directories,
205
+ environment overrides, and an already-installed target. It does not launch a client or verify that
206
+ the client can load the skill. Cursor detection deliberately relies on `~/.cursor` rather than the
207
+ ambiguous `agent` executable name. Because some clients also scan another client's compatibility
208
+ directories, prefer an explicit target and use one if the same skill appears more than once.
209
+
210
+ Every selected destination is preflighted before writing or removing files. A small hidden manifest
211
+ records hashes of the managed files; it is installer metadata, not another instruction loaded by the
212
+ agent. This lets an untouched older installation upgrade without treating it as a user edit.
213
+ Uninstall removes only managed files whose content is still recognized and leaves extra user files
214
+ in place. Use `--force` only when you intentionally want to replace or remove a modified managed
215
+ file. `--dry-run` performs the same checks and reports the planned action without changing files.
216
+
171
217
  Prewarm, inspect, or remove the per-repository index:
172
218
 
173
219
  ```bash
@@ -187,7 +233,7 @@ The repository publishes two recorded development comparisons. Both measure
187
233
  scores must not be merged into one leaderboard. The shared Java runner reproduces all six methods;
188
234
  the multilingual public runner currently reproduces BM25, Probe, and ripgrep, while the other three
189
235
  rows retain their recorded implementation identities and per-task output. The Code Search rows
190
- describe the source revisions recorded by each benchmark, not a new measurement of version 0.2.0.
236
+ describe the source revisions recorded by each benchmark, not a new measurement of the current release.
191
237
 
192
238
  ### Shared Java comparison
193
239
 
@@ -305,7 +351,8 @@ validation remain future work.
305
351
  executable patch tests and repeated model runs.
306
352
  - **P1, retrieval quality:** close the long-query ranking gaps surfaced by the multilingual
307
353
  diagnostic, and add stronger AST/symbol parsers.
308
- - **P1, onboarding breadth:** add safe CLI/skill installers for more coding agents. Consider MCP only
354
+ - **P1, onboarding validation:** expand beyond the seven current user-level Agent Skill destinations
355
+ only when another integration has a real discovery path and automated coverage. Consider MCP only
309
356
  if a resident index or structured tool discovery provides a measured benefit over CLI invocation.
310
357
  - **P2, distribution:** ship signed standalone binaries.
311
358
 
@@ -314,7 +361,7 @@ validation remain future work.
314
361
  This is a testable experimental MVP, not a production release. The public development benchmark
315
362
  measures retrieval, while the deterministic fixtures and tests cover output behavior and package
316
363
  quality. None of them proves held-out retrieval superiority or executable patch success. The
317
- implementation and bundled Codex skill are independently designed around the task-evidence workflow.
364
+ implementation and bundled Agent Skill are independently designed around the task-evidence workflow.
318
365
 
319
366
  ## License
320
367
 
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-search-cli"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Task-aware code search with compact, auditable evidence for coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  license = "Apache-2.0"
12
12
  authors = [{name = "Code Search contributors"}]
13
- keywords = ["code-search", "code-retrieval", "coding-agents", "cli", "codex"]
13
+ keywords = ["code-search", "code-retrieval", "coding-agents", "agent-skills", "cli", "codex"]
14
14
  dependencies = []
15
15
  classifiers = [
16
16
  "Development Status :: 3 - Alpha",
@@ -24,8 +24,13 @@ def main() -> int:
24
24
  root = Path(temporary)
25
25
  repository = root / "gson"
26
26
  environment = os.environ.copy()
27
+ environment["HOME"] = str(root / "home")
27
28
  environment["CODE_SEARCH_CACHE_HOME"] = str(root / "cache")
28
29
  environment["CODEX_HOME"] = str(root / "codex")
30
+ environment["CLAUDE_CONFIG_DIR"] = str(root / "claude")
31
+ environment["GEMINI_CLI_HOME"] = str(root / "gemini-home")
32
+ environment["OPENCODE_CONFIG_DIR"] = str(root / "opencode")
33
+ environment["COPILOT_HOME"] = str(root / "copilot")
29
34
 
30
35
  _checkout(repository)
31
36
  _configure_ignored_sentinel(repository)
@@ -36,10 +41,52 @@ def main() -> int:
36
41
  reported_version = _run((*CLI, "--version"), environment=environment)
37
42
  _require(reported_version == f"code-search {installed_version}", "CLI version mismatch")
38
43
 
44
+ agent_labels = {
45
+ "codex": "Codex",
46
+ "claude-code": "Claude Code",
47
+ "cursor": "Cursor",
48
+ "gemini": "Gemini CLI",
49
+ "opencode": "OpenCode",
50
+ "github-copilot": "GitHub Copilot",
51
+ "kiro": "Kiro",
52
+ }
53
+ for target, label in agent_labels.items():
54
+ dry_run = _run(
55
+ (*CLI, "install", "--target", target, "--dry-run"),
56
+ environment=environment,
57
+ )
58
+ _require(
59
+ f"{label} skill would be created" in dry_run,
60
+ f"{label} skill dry-run was not reported",
61
+ )
62
+ _require(
63
+ not list(root.glob("**/skills/code-search")),
64
+ "skill dry-run wrote files",
65
+ )
66
+
39
67
  first_install = _run((*CLI, "install"), environment=environment)
40
68
  second_install = _run((*CLI, "install"), environment=environment)
41
- _require("created" in first_install, "first skill installation was not created")
42
- _require("unchanged" in second_install, "second skill installation was not idempotent")
69
+ _require("Codex skill created" in first_install, "default Codex installation was not created")
70
+ _require(
71
+ "Codex skill unchanged" in second_install,
72
+ "default Codex installation was not idempotent",
73
+ )
74
+ for target, label in agent_labels.items():
75
+ output = _run((*CLI, "install", "--target", target), environment=environment)
76
+ expected_action = "unchanged" if target == "codex" else "created"
77
+ _require(
78
+ f"{label} skill {expected_action}" in output,
79
+ f"{label} skill installation failed",
80
+ )
81
+ repeated = _run((*CLI, "install", "--target", target), environment=environment)
82
+ _require(
83
+ f"{label} skill unchanged" in repeated,
84
+ f"{label} installation was not idempotent",
85
+ )
86
+
87
+ detected = _run((*CLI, "install", "--target", "detected"), environment=environment)
88
+ for label in agent_labels.values():
89
+ _require(f"{label} skill unchanged" in detected, f"detected installation missed {label}")
43
90
 
44
91
  first_index = _json_cli("index", "--repo", repository, "--format", "json", environment=environment)
45
92
  _require(first_index["source_files"] > 0, "public repository index is empty")
@@ -9,7 +9,13 @@ from importlib.metadata import PackageNotFoundError, version
9
9
 
10
10
  from .engine import RetrievalEngine
11
11
  from .index_store import PersistentIndex
12
- from .installer import install_codex_skill, uninstall_codex_skill
12
+ from .installer import (
13
+ AGENT_SELECTORS,
14
+ AgentName,
15
+ agent_display_name,
16
+ install_skills,
17
+ uninstall_skills,
18
+ )
13
19
  from .models import Evidence
14
20
  from .repository import RETRIEVAL_SCOPES, RepositoryReader
15
21
 
@@ -51,11 +57,25 @@ def build_parser() -> argparse.ArgumentParser:
51
57
  clean = subparsers.add_parser("clean", help="remove the persistent index for a repository")
52
58
  _repository_args(clean)
53
59
 
54
- install = subparsers.add_parser("install", help="install the bundled Codex skill")
60
+ install = subparsers.add_parser("install", help="install the bundled skill for a coding agent")
61
+ install.add_argument(
62
+ "--target",
63
+ choices=AGENT_SELECTORS,
64
+ default="codex",
65
+ help="agent destination; 'detected' uses best-effort local signals (default: codex)",
66
+ )
55
67
  install.add_argument("--force", action="store_true", help="replace a locally modified installed skill")
56
-
57
- uninstall = subparsers.add_parser("uninstall", help="remove the bundled Codex skill")
68
+ install.add_argument("--dry-run", action="store_true", help="preview changes without writing files")
69
+
70
+ uninstall = subparsers.add_parser("uninstall", help="remove the bundled skill for a coding agent")
71
+ uninstall.add_argument(
72
+ "--target",
73
+ choices=AGENT_SELECTORS,
74
+ default="codex",
75
+ help="agent destination; 'detected' uses best-effort local signals (default: codex)",
76
+ )
58
77
  uninstall.add_argument("--force", action="store_true", help="remove a locally modified installed skill")
78
+ uninstall.add_argument("--dry-run", action="store_true", help="preview changes without removing files")
59
79
  return parser
60
80
 
61
81
 
@@ -63,11 +83,14 @@ def main(argv: list[str] | None = None) -> int:
63
83
  args = build_parser().parse_args(argv)
64
84
  try:
65
85
  if args.command in {"install", "uninstall"}:
66
- operation = install_codex_skill if args.command == "install" else uninstall_codex_skill
67
- path, action = operation(force=args.force)
68
- print(f"Codex skill {action}: {path}")
69
- if args.command == "install":
70
- print("Restart Codex to load the skill.")
86
+ operation = install_skills if args.command == "install" else uninstall_skills
87
+ results = operation(target=args.target, force=args.force, dry_run=args.dry_run)
88
+ for result in results:
89
+ action = f"would be {result.action}" if args.dry_run else result.action
90
+ print(f"{agent_display_name(result.agent)} skill {action}: {result.path}")
91
+ if args.command == "install" and not args.dry_run:
92
+ for result in results:
93
+ print(_skill_reload_hint(result.agent))
71
94
  return 0
72
95
 
73
96
  if args.command in {"index", "status", "clean"}:
@@ -128,6 +151,16 @@ def _non_empty(value: str) -> str:
128
151
  return value
129
152
 
130
153
 
154
+ def _skill_reload_hint(agent: AgentName) -> str:
155
+ if agent == "codex":
156
+ return "Restart Codex if the skill does not appear automatically."
157
+ if agent == "gemini":
158
+ return "Run /skills reload in Gemini CLI if the skill does not appear automatically."
159
+ if agent == "kiro":
160
+ return "Kiro loads Agent Skills automatically; reopen the session if it is not listed."
161
+ return f"Restart {agent_display_name(agent)} if the skill does not appear automatically."
162
+
163
+
131
164
  def _evidence_json(evidence: list[Evidence]) -> str:
132
165
  from dataclasses import asdict
133
166