claude-smart 0.2.24 → 0.2.25

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/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  <img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License">
14
14
  </a>
15
15
  <a href="plugin/pyproject.toml">
16
- <img src="https://img.shields.io/badge/version-0.2.24-green.svg" alt="Version">
16
+ <img src="https://img.shields.io/badge/version-0.2.25-green.svg" alt="Version">
17
17
  </a>
18
18
  <a href="plugin/pyproject.toml">
19
19
  <img src="https://img.shields.io/badge/python-%3E%3D3.12-brightgreen.svg" alt="Python">
@@ -118,13 +118,18 @@ You need the `codex` CLI on `PATH` and Node.js available for `npx`:
118
118
  npx claude-smart install --host codex
119
119
  ```
120
120
 
121
- The helper registers the bundled **ReflexioAI** marketplace with Codex and
122
- enables Codex plugin hooks. Then:
121
+ The helper registers the bundled **ReflexioAI** marketplace with Codex, enables
122
+ Codex's `plugin_hooks` feature, installs `claude-smart` into Codex's local
123
+ plugin cache, and enables it in `~/.codex/config.toml`. Hooks are not active in
124
+ already-running Codex windows; after the command finishes:
123
125
 
124
- 1. Fully quit and reopen Codex in your project.
125
- 2. Run `/plugins`.
126
- 3. Install `claude-smart` from the **ReflexioAI** marketplace.
127
- 4. Restart Codex again so hooks reload.
126
+ 1. Fully quit and reopen Codex in your project so hooks reload.
127
+ 2. Run `/plugins` only if you want to verify `claude-smart` shows as installed
128
+ from the **ReflexioAI** marketplace.
129
+
130
+ If you install or toggle `claude-smart` manually from `/plugins`, still run
131
+ `npx claude-smart install --host codex` once afterward so `plugin_hooks` is
132
+ enabled and the cache/config are prepared.
128
133
 
129
134
  Do not create a `~/plugins/claude-smart` symlink for a normal `npx` install;
130
135
  that symlink is only for plugin development from a cloned checkout.
@@ -186,7 +191,7 @@ claude-smart builds three artifacts as you work and injects the relevant ones in
186
191
 
187
192
  Skills clean themselves up: correct the same thing twice and they merge; change your mind and the old one is archived.
188
193
 
189
- Under the hood: hooks watch your turns, tool calls, and assistant replies, auto-flagging corrections (or anything you flag with `/learn`). At session end (or on `/learn`), [reflexio](https://github.com/ReflexioAI/reflexio) — the self-improving engine that powers claude-smart — extracts preferences and project-specific skills, then rolls durable patterns into shared skills. On each new user prompt, claude-smart searches for matching context and injects only the relevant hits. Run `/show` or the equivalent CLI command to audit the current learned state. Everything runs on your machine.
194
+ Under the hood: hooks watch your turns, tool calls, and assistant replies, auto-flagging corrections (or anything you flag with `/claude-smart:learn`). At session end (or on `/claude-smart:learn`), [reflexio](https://github.com/ReflexioAI/reflexio) — the self-improving engine that powers claude-smart — extracts preferences and project-specific skills, then rolls durable patterns into shared skills. On each new user prompt, claude-smart searches for matching context and injects only the relevant hits. Run `/claude-smart:show` or the equivalent CLI command to audit the current learned state. Everything runs on your machine.
190
195
 
191
196
  **Citations.** At the end of a reply, the assistant may append a short marker:
192
197
 
@@ -205,16 +210,17 @@ See [ARCHITECTURE.md](./ARCHITECTURE.md) for hooks, data flow, and reflexio deta
205
210
 
206
211
  ## Commands
207
212
 
208
- Claude Code installs these as slash commands. In Codex, run the equivalent shell
209
- command directly, or ask Codex to run it.
213
+ Claude Code installs these as plugin slash commands. Codex does not currently
214
+ support these plugin-provided slash commands, so run the equivalent shell command
215
+ directly, or ask Codex to run it.
210
216
 
211
217
  | Claude Code | Codex / shell | What it does |
212
218
  | --- | --- | --- |
213
- | `/dashboard` | `bash ~/.reflexio/plugin-root/scripts/dashboard-open.sh` | Open the dashboard in your browser, auto-starting the reflexio backend and dashboard services if they aren't already running. |
214
- | `/show` | `bash ~/.reflexio/plugin-root/scripts/cli.sh show` | Print current project-specific skills, shared skills, and the current project's preferences so you can audit learned state manually. |
215
- | `/learn [note]` | `bash ~/.reflexio/plugin-root/scripts/cli.sh learn --note "optional note"` | Flag the most recent turn as a correction (for cases the automatic heuristic missed) and force reflexio to run extraction *now* on the session's unpublished interactions. The optional note becomes the correction description the extractor sees. |
216
- | `/restart` | `bash ~/.reflexio/plugin-root/scripts/cli.sh restart` | Restart the reflexio backend and dashboard to pick up new changes (e.g. after upgrading the plugin or editing local reflexio code). |
217
- | `/clear-all` | `bash ~/.reflexio/plugin-root/scripts/cli.sh clear-all --yes` | **Destructive.** Delete *all* reflexio interactions, preferences, and skills. Use when you want to wipe learned state and start fresh. |
219
+ | `/claude-smart:dashboard` | `bash ~/.reflexio/plugin-root/scripts/dashboard-open.sh` | Open the dashboard in your browser, auto-starting the reflexio backend and dashboard services if they aren't already running. |
220
+ | `/claude-smart:show` | `bash ~/.reflexio/plugin-root/scripts/cli.sh show` | Print current project-specific skills, shared skills, and the current project's preferences so you can audit learned state manually. |
221
+ | `/claude-smart:learn [note]` | `bash ~/.reflexio/plugin-root/scripts/cli.sh learn --note "optional note"` | Flag the most recent turn as a correction (for cases the automatic heuristic missed) and force reflexio to run extraction *now* on the session's unpublished interactions. The optional note becomes the correction description the extractor sees. |
222
+ | `/claude-smart:restart` | `bash ~/.reflexio/plugin-root/scripts/cli.sh restart` | Restart the reflexio backend and dashboard to pick up new changes (e.g. after upgrading the plugin or editing local reflexio code). |
223
+ | `/claude-smart:clear-all` | `bash ~/.reflexio/plugin-root/scripts/cli.sh clear-all --yes` | **Destructive.** Delete *all* reflexio interactions, preferences, and skills. Use when you want to wipe learned state and start fresh. |
218
224
 
219
225
  ---
220
226
 
@@ -231,7 +237,7 @@ Advanced users can tune claude-smart via environment variables — see [DEVELOPE
231
237
  | `.claude/settings.local.json` or `~/.claude/settings.json` | Claude Code hook environment, such as `CLAUDE_SMART_ENABLE_OPTIMIZER`; use project-local settings for one repo or user settings for all projects. |
232
238
  | `~/.codex/config.toml` | Codex feature flags, including `plugin_hooks = true` after `claude-smart install --host codex`. |
233
239
  | `~/.codex/plugins/cache/reflexioai/claude-smart/<version>/` | Codex's cached install of the `claude-smart` plugin from the `ReflexioAI` marketplace. |
234
- | `~/.reflexio/plugin-root` | Self-healed symlink to the active plugin dir (managed by `ensure-plugin-root.sh` — written on install, refreshed each `SessionStart`). Slash commands resolve through it, so don't delete it; if you do, the next session will recreate it. |
240
+ | `~/.reflexio/plugin-root` | Self-healed symlink to the active plugin dir (managed by `ensure-plugin-root.sh` — written on install, refreshed each `SessionStart`). Claude Code slash commands and Codex shell-command helpers resolve through it, so don't delete it; if you do, the next session will recreate it. |
235
241
  | `~/.claude-smart/sessions/{session_id}.jsonl` | Per-session buffer. User turns, assistant turns, tool invocations, `{"published_up_to": N}` watermarks. Safe to inspect and safe to delete — everything past the latest watermark has already been written to reflexio's DB. |
236
242
  | `~/.cache/chroma/onnx_models/all-MiniLM-L6-v2/` | Cached ONNX weights (~86 MB, downloaded once). Delete to force a re-download. |
237
243
 
@@ -206,7 +206,8 @@ function printHelp() {
206
206
  ` 1. Copies the bundled marketplace to ${CODEX_MARKETPLACE_DIR}`,
207
207
  " 2. codex plugin marketplace add <copied marketplace>",
208
208
  " 3. codex features enable plugin_hooks",
209
- " 4. Fully quit and reopen Codex, run /plugins, install claude-smart, then restart Codex.",
209
+ " 4. Installs claude-smart into Codex's plugin cache and enables it",
210
+ " 5. Restart Codex.",
210
211
  "",
211
212
  "Update:",
212
213
  " npx claude-smart update Update to the latest version",
@@ -344,6 +345,50 @@ function cleanupCodexInstallState() {
344
345
  }
345
346
  }
346
347
 
348
+ function setCodexPluginEnabled() {
349
+ const sectionName = `plugins."${CODEX_PLUGIN_ID}"`;
350
+ removeTomlSections(CODEX_CONFIG_PATH, { exact: new Set([sectionName]) });
351
+ const existing = existsSync(CODEX_CONFIG_PATH)
352
+ ? readFileSync(CODEX_CONFIG_PATH, "utf8")
353
+ : "";
354
+ let next = existing;
355
+ if (next && !next.endsWith("\n")) next += "\n";
356
+ if (next.trim()) next += "\n";
357
+ next += `[${sectionName}]\nenabled = true\n`;
358
+ mkdirSync(dirname(CODEX_CONFIG_PATH), { recursive: true });
359
+ writeFileSync(CODEX_CONFIG_PATH, next);
360
+ }
361
+
362
+ function codexPluginVersion(pluginRoot) {
363
+ try {
364
+ const manifest = JSON.parse(
365
+ readFileSync(join(pluginRoot, ".codex-plugin", "plugin.json"), "utf8"),
366
+ );
367
+ return typeof manifest.version === "string" && manifest.version
368
+ ? manifest.version
369
+ : null;
370
+ } catch {
371
+ return null;
372
+ }
373
+ }
374
+
375
+ function installCodexPluginCache(pluginRoot) {
376
+ const version = codexPluginVersion(pluginRoot);
377
+ if (!version) {
378
+ throw new Error(`missing version in ${join(pluginRoot, ".codex-plugin", "plugin.json")}`);
379
+ }
380
+ const cacheDir = join(CODEX_PLUGIN_CACHE_DIR, version);
381
+ rmSync(cacheDir, { recursive: true, force: true });
382
+ mkdirSync(dirname(cacheDir), { recursive: true });
383
+ cpSync(pluginRoot, cacheDir, {
384
+ recursive: true,
385
+ force: true,
386
+ verbatimSymlinks: false,
387
+ });
388
+ setCodexPluginEnabled();
389
+ return cacheDir;
390
+ }
391
+
347
392
  async function runUpdate() {
348
393
  if (!hasClaudeCli()) {
349
394
  process.stderr.write(
@@ -476,6 +521,20 @@ async function runInstallCodex() {
476
521
  process.exit(code);
477
522
  }
478
523
 
524
+ let cacheDir = null;
525
+ try {
526
+ cacheDir = installCodexPluginCache(join(marketplaceRoot, CODEX_MARKETPLACE_PLUGIN_PATH));
527
+ process.stdout.write(`Installed Codex plugin cache at ${cacheDir}.\n`);
528
+ } catch (err) {
529
+ process.stderr.write(
530
+ `error: automatic Codex plugin install failed: ${err && err.message ? err.message : err}\n`,
531
+ );
532
+ process.stderr.write(
533
+ `Open Codex, run /plugins, and install claude-smart from the ${CODEX_MARKETPLACE_DISPLAY_NAME} marketplace manually.\n`,
534
+ );
535
+ process.exit(1);
536
+ }
537
+
479
538
  const added = seedReflexioEnv();
480
539
  if (added.length > 0) {
481
540
  process.stdout.write(`Seeded ${REFLEXIO_ENV_PATH} with ${added.join(", ")}.\n`);
@@ -484,8 +543,8 @@ async function runInstallCodex() {
484
543
  process.stdout.write(
485
544
  [
486
545
  "",
487
- "claude-smart Codex support is prepared.",
488
- `Fully quit and reopen Codex, run /plugins, install claude-smart from the ${CODEX_MARKETPLACE_DISPLAY_NAME} marketplace, then restart Codex so hooks reload.`,
546
+ "claude-smart Codex support is installed.",
547
+ `Restart Codex so the installed plugin and hooks reload. /plugins should show claude-smart as installed from the ${CODEX_MARKETPLACE_DISPLAY_NAME} marketplace.`,
489
548
  "Local data is shared with Claude Code under ~/.reflexio/ and ~/.claude-smart/.",
490
549
  "",
491
550
  ].join("\n"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-smart",
3
- "version": "0.2.24",
3
+ "version": "0.2.25",
4
4
  "description": "Self-improving Claude Code plugin — learns from corrections via reflexio",
5
5
  "keywords": [
6
6
  "claude",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-smart",
3
- "version": "0.2.24",
3
+ "version": "0.2.25",
4
4
  "description": "Self-improving Claude Code plugin — learns from corrections across sessions via reflexio",
5
5
  "author": {
6
6
  "name": "Yi Lu"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-smart",
3
- "version": "0.2.24",
3
+ "version": "0.2.25",
4
4
  "description": "Self-improving coding assistant plugin — learns from corrections across sessions via reflexio",
5
5
  "author": {
6
6
  "name": "Yi Lu"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "claude-smart"
3
- version = "0.2.24"
3
+ version = "0.2.25"
4
4
  description = "Self-improving Claude Code plugin — learns from corrections via reflexio"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -315,6 +315,59 @@ def _remove_toml_sections(
315
315
  return True
316
316
 
317
317
 
318
+ def _set_codex_plugin_enabled(path: Path) -> bool:
319
+ """Write Codex's installed-plugin config section for claude-smart."""
320
+ section_name = f'plugins."{_CODEX_PLUGIN_ID}"'
321
+ if not _remove_toml_sections(path, exact={section_name}):
322
+ return False
323
+ try:
324
+ text = path.read_text() if path.exists() else ""
325
+ except OSError:
326
+ return False
327
+ if text and not text.endswith("\n"):
328
+ text += "\n"
329
+ if text.strip():
330
+ text += "\n"
331
+ text += f"[{section_name}]\nenabled = true\n"
332
+ try:
333
+ path.parent.mkdir(parents=True, exist_ok=True)
334
+ path.write_text(text)
335
+ except OSError:
336
+ return False
337
+ return True
338
+
339
+
340
+ def _codex_plugin_version(plugin_root: Path) -> str | None:
341
+ try:
342
+ manifest = json.loads(
343
+ (plugin_root / ".codex-plugin" / "plugin.json").read_text()
344
+ )
345
+ except (OSError, json.JSONDecodeError):
346
+ return None
347
+ version = manifest.get("version")
348
+ return version if isinstance(version, str) and version else None
349
+
350
+
351
+ def _install_codex_plugin_cache(plugin_root: Path) -> tuple[bool, str]:
352
+ """Best-effort local install equivalent to selecting Install in /plugins."""
353
+ version = _codex_plugin_version(plugin_root)
354
+ if not version:
355
+ return (
356
+ False,
357
+ f"missing version in {plugin_root / '.codex-plugin' / 'plugin.json'}",
358
+ )
359
+ cache_dir = _CODEX_PLUGIN_CACHE_DIR / version
360
+ try:
361
+ shutil.rmtree(cache_dir, ignore_errors=True)
362
+ cache_dir.parent.mkdir(parents=True, exist_ok=True)
363
+ shutil.copytree(plugin_root, cache_dir, symlinks=False, ignore=_COPYTREE_IGNORE)
364
+ except OSError as exc:
365
+ return False, f"could not write Codex plugin cache: {exc}"
366
+ if not _set_codex_plugin_enabled(_CODEX_CONFIG_PATH):
367
+ return False, f"could not enable {_CODEX_PLUGIN_ID} in {_CODEX_CONFIG_PATH}"
368
+ return True, f"installed Codex plugin cache at {cache_dir}"
369
+
370
+
318
371
  def _cleanup_codex_install_state() -> bool:
319
372
  """Remove Codex's local install artifacts while preserving shared learning data.
320
373
 
@@ -446,14 +499,30 @@ def cmd_install_codex(_args: argparse.Namespace) -> int:
446
499
  else:
447
500
  sys.stderr.write(f"warning: {registration_msg}\n")
448
501
 
502
+ installed = False
503
+ install_msg = "marketplace registration failed"
449
504
  if registered:
505
+ installed, install_msg = _install_codex_plugin_cache(
506
+ marketplace_root / _CODEX_LOCAL_PLUGIN_PATH
507
+ )
508
+ if installed:
509
+ sys.stdout.write(f"{install_msg}.\n")
510
+ else:
511
+ sys.stderr.write(f"warning: {install_msg}\n")
512
+
513
+ if registered and installed:
514
+ sys.stdout.write(
515
+ "\nclaude-smart Codex support is installed.\n"
516
+ "Restart Codex so the installed plugin and hooks reload. /plugins should "
517
+ f"show claude-smart as installed from the {_CODEX_MARKETPLACE_DISPLAY_NAME} marketplace. "
518
+ "Uninstall removes the plugin cache and marketplace registration but leaves "
519
+ "shared claude-smart data and Codex's global plugin_hooks feature intact.\n"
520
+ )
521
+ elif registered:
450
522
  sys.stdout.write(
451
- "\nclaude-smart Codex support is prepared.\n"
523
+ "\nclaude-smart Codex marketplace is prepared, but automatic plugin install failed.\n"
452
524
  "Fully quit and reopen Codex in this repo, run /plugins, install claude-smart from "
453
- f"the {_CODEX_MARKETPLACE_DISPLAY_NAME} marketplace if it is not already installed, "
454
- "then restart Codex so hooks reload. Uninstall removes the marketplace "
455
- "registration but leaves shared claude-smart data and Codex's global "
456
- "plugin_hooks feature intact.\n"
525
+ f"the {_CODEX_MARKETPLACE_DISPLAY_NAME} marketplace, and restart Codex so hooks reload.\n"
457
526
  )
458
527
  else:
459
528
  sys.stdout.write(
@@ -462,7 +531,7 @@ def cmd_install_codex(_args: argparse.Namespace) -> int:
462
531
  "then fully quit and reopen Codex, run /plugins, install claude-smart from the "
463
532
  f"{_CODEX_MARKETPLACE_DISPLAY_NAME} marketplace, and restart Codex so hooks reload.\n"
464
533
  )
465
- return 0 if hooks_ok and registered else 1
534
+ return 0 if hooks_ok and registered and installed else 1
466
535
 
467
536
 
468
537
  def cmd_install(args: argparse.Namespace) -> int:
package/plugin/uv.lock CHANGED
@@ -419,7 +419,7 @@ wheels = [
419
419
 
420
420
  [[package]]
421
421
  name = "claude-smart"
422
- version = "0.2.24"
422
+ version = "0.2.25"
423
423
  source = { editable = "." }
424
424
  dependencies = [
425
425
  { name = "chromadb" },