claude-smart 0.2.40 → 0.2.41

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.40-green.svg" alt="Version">
16
+ <img src="https://img.shields.io/badge/version-0.2.41-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">
@@ -508,14 +508,14 @@ function runChecked(command, args, options = {}) {
508
508
  });
509
509
  }
510
510
 
511
- function runPluginService(pluginRoot, scriptName, subcommand) {
511
+ function runPluginService(pluginRoot, scriptName, subcommand, envOverrides = {}) {
512
512
  const script = join(pluginRoot, "scripts", scriptName);
513
513
  if (!existsSync(script)) return false;
514
514
  const bash = resolveCommand(isWindows() ? ["bash.exe", "bash"] : ["bash"]);
515
515
  if (!bash) return false;
516
516
  const result = spawnSync(bash, [script, subcommand], {
517
517
  cwd: pluginRoot,
518
- env: runtimeEnv(),
518
+ env: { ...runtimeEnv(), ...envOverrides },
519
519
  stdio: "ignore",
520
520
  windowsHide: true,
521
521
  timeout: PLUGIN_SERVICE_TIMEOUT_MS,
@@ -542,6 +542,12 @@ function refreshDashboardService(pluginRoot) {
542
542
  return runPluginService(pluginRoot, "dashboard-service.sh", "start");
543
543
  }
544
544
 
545
+ function startBackendService(pluginRoot, host) {
546
+ return runPluginService(pluginRoot, "backend-service.sh", "start", {
547
+ CLAUDE_SMART_HOST: host,
548
+ });
549
+ }
550
+
545
551
  function stopClaudeSmartServices(pluginRoot) {
546
552
  runPluginService(pluginRoot, "dashboard-service.sh", "stop");
547
553
  runPluginService(pluginRoot, "backend-service.sh", "stop");
@@ -834,9 +840,7 @@ function patchCodexHooksForNode(pluginRoot, nodePath) {
834
840
  const runner = join(pluginRoot, "scripts", "codex-hook.js");
835
841
  const command = (...args) => [nodePath, runner, ...args].map(quoteCommandPart).join(" ");
836
842
  // Dispatch by command content rather than index — entries can be added or
837
- // reordered (e.g. the SessionStart install hook at index 0) without
838
- // breaking the patch. Entries that must run as bash (smart-install.sh)
839
- // are left untouched.
843
+ // reordered without breaking the patch.
840
844
  const patchOne = (original) => {
841
845
  if (typeof original !== "string") return original;
842
846
  if (original.includes("smart-install.sh")) return original;
@@ -1512,6 +1516,9 @@ async function runInstall(args) {
1512
1516
  process.stdout.write("Installed read-only hook manifest; publish interactions hooks are disabled.\n");
1513
1517
  }
1514
1518
  process.stdout.write(`Prepared claude-smart runtime at ${pluginRoot}.\n`);
1519
+ if (startBackendService(pluginRoot, "claude-code")) {
1520
+ process.stdout.write("Started claude-smart backend service.\n");
1521
+ }
1515
1522
  if (refreshDashboardService(pluginRoot)) {
1516
1523
  process.stdout.write("Refreshed claude-smart dashboard service.\n");
1517
1524
  }
@@ -1592,6 +1599,9 @@ async function runInstallCodex(args) {
1592
1599
  if (readOnly) {
1593
1600
  process.stdout.write("Installed read-only hook manifest; publish interactions hooks are disabled.\n");
1594
1601
  }
1602
+ if (startBackendService(cacheDir, "codex")) {
1603
+ process.stdout.write("Started claude-smart backend service.\n");
1604
+ }
1595
1605
  if (refreshDashboardService(cacheDir)) {
1596
1606
  process.stdout.write("Refreshed claude-smart dashboard service.\n");
1597
1607
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-smart",
3
- "version": "0.2.40",
3
+ "version": "0.2.41",
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.40",
3
+ "version": "0.2.41",
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.40",
3
+ "version": "0.2.41",
4
4
  "description": "Self-improving coding assistant plugin — learns from corrections across sessions via reflexio",
5
5
  "author": {
6
6
  "name": "Yi Lu"
@@ -5,11 +5,6 @@
5
5
  {
6
6
  "matcher": "startup|resume",
7
7
  "hooks": [
8
- {
9
- "type": "command",
10
- "command": "_R=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; [ -z \"$_R\" ] && _R=$(ls -dt \"$HOME/.codex/plugins/cache/reflexioai/claude-smart\"/*/ 2>/dev/null | head -n 1); [ -n \"$_R\" ] && . \"${_R%/}/scripts/_codex_env.sh\" && bash \"$_R/scripts/smart-install.sh\" || true",
11
- "timeout": 300
12
- },
13
8
  {
14
9
  "type": "command",
15
10
  "command": "_R=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; [ -z \"$_R\" ] && _R=$(ls -dt \"$HOME/.codex/plugins/cache/reflexioai/claude-smart\"/*/ 2>/dev/null | head -n 1); [ -n \"$_R\" ] && . \"${_R%/}/scripts/_codex_env.sh\" && bash \"$_R/scripts/ensure-plugin-root.sh\" \"$_R\" || true",
@@ -14,16 +14,6 @@
14
14
  }
15
15
  ],
16
16
  "SessionStart": [
17
- {
18
- "matcher": "startup|clear|compact|resume",
19
- "hooks": [
20
- {
21
- "type": "command",
22
- "command": "_R=\"${CLAUDE_PLUGIN_ROOT}\"; [ -z \"$_R\" ] && _R=\"$HOME/.claude/plugins/marketplaces/reflexioai/plugin\"; bash \"$_R/scripts/smart-install.sh\"",
23
- "timeout": 300
24
- }
25
- ]
26
- },
27
17
  {
28
18
  "matcher": "startup|clear|compact|resume",
29
19
  "hooks": [
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "claude-smart"
3
- version = "0.2.40"
3
+ version = "0.2.41"
4
4
  description = "Self-improving Claude Code plugin — learns from corrections via reflexio"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -201,13 +201,13 @@ case "$CMD" in
201
201
  fi
202
202
  if ! command -v uv >/dev/null 2>&1; then
203
203
  if [ "${CLAUDE_SMART_BOOTSTRAPPING:-}" != "1" ] && [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
204
- claude_smart_append_capped_log "$LOG_FILE" "$LOG_MAX_BYTES" "[claude-smart] backend: uv not on PATH; running installer"
205
- CLAUDE_SMART_BOOTSTRAPPING=1 bash "$PLUGIN_ROOT/scripts/smart-install.sh" >>"$STATE_DIR/install.log" 2>&1 || true
206
- claude_smart_source_login_path
207
- claude_smart_prepend_astral_bins
204
+ claude_smart_append_capped_log "$LOG_FILE" "$LOG_MAX_BYTES" "[claude-smart] backend: uv not on PATH; starting installer in background"
205
+ claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
206
+ bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
207
+ >>"$STATE_DIR/install.log" 2>&1 || true
208
208
  fi
209
209
  if ! command -v uv >/dev/null 2>&1; then
210
- claude_smart_append_capped_log "$LOG_FILE" "$LOG_MAX_BYTES" "[claude-smart] backend: uv not on PATH after installer; skipping"
210
+ claude_smart_append_capped_log "$LOG_FILE" "$LOG_MAX_BYTES" "[claude-smart] backend: uv not on PATH; installer recovery scheduled; skipping"
211
211
  emit_ok; exit 0
212
212
  fi
213
213
  fi
@@ -302,33 +302,6 @@ function detached(command, args, options = {}) {
302
302
  return child.pid;
303
303
  }
304
304
 
305
- function runInstaller(root, reason) {
306
- if (process.env.CLAUDE_SMART_BOOTSTRAPPING === "1") return false;
307
- const script = path.join(root, "scripts", "smart-install.sh");
308
- if (!fs.existsSync(script)) return false;
309
- const bash = bashPath();
310
- if (!bash) return false;
311
- appendLog("backend.log", `[claude-smart] ${reason}; running installer`);
312
- const result = spawnSync(bash, [script], {
313
- cwd: root,
314
- env: {
315
- ...process.env,
316
- CLAUDE_SMART_BOOTSTRAPPING: "1",
317
- },
318
- encoding: "utf8",
319
- maxBuffer: 20 * 1024 * 1024,
320
- windowsHide: true,
321
- });
322
- const output = `${result.stdout || ""}${result.stderr || ""}`.trim();
323
- if (output) {
324
- ensureDir(STATE_DIR);
325
- fs.appendFileSync(path.join(STATE_DIR, "install.log"), `${output}\n`);
326
- trimLog(path.join(STATE_DIR, "install.log"));
327
- }
328
- prependRuntimePath();
329
- return result.status === 0;
330
- }
331
-
332
305
  function startInstallerDetached(root, reason) {
333
306
  if (process.env.CLAUDE_SMART_BOOTSTRAPPING === "1") return false;
334
307
  const script = path.join(root, "scripts", "smart-install.sh");
@@ -410,11 +383,11 @@ async function startBackend(root) {
410
383
  }
411
384
  const uv = uvPath();
412
385
  if (!uv) {
413
- runInstaller(root, "backend: uv not on PATH");
386
+ startInstallerDetached(root, "backend: uv not on PATH");
414
387
  }
415
388
  const readyUv = uvPath();
416
389
  if (!readyUv) {
417
- appendLog("backend.log", "[claude-smart] backend: uv not on PATH after installer; skipping");
390
+ appendLog("backend.log", "[claude-smart] backend: uv not on PATH; installer recovery scheduled; skipping");
418
391
  emitOk();
419
392
  return;
420
393
  }
@@ -478,11 +451,11 @@ async function startDashboard(root) {
478
451
  }
479
452
  const npm = npmPath();
480
453
  if (!npm) {
481
- runInstaller(root, "dashboard: npm not on PATH");
454
+ startInstallerDetached(root, "dashboard: npm not on PATH");
482
455
  }
483
456
  const readyNpm = npmPath();
484
457
  if (!readyNpm) {
485
- appendLog("dashboard.log", "[claude-smart] dashboard: npm not on PATH after installer; skipping");
458
+ appendLog("dashboard.log", "[claude-smart] dashboard: npm not on PATH; installer recovery scheduled; skipping");
486
459
  emitOk();
487
460
  return;
488
461
  }
@@ -512,14 +485,10 @@ function runHook(root, event) {
512
485
  trimLog(path.join(STATE_DIR, "backend.log"));
513
486
  let uv = uvPath();
514
487
  if (!uv) {
515
- if (event === "session-start") {
516
- runInstaller(root, "hook: uv not on PATH");
517
- uv = uvPath();
518
- } else {
519
- startInstallerDetached(root, "hook: uv not on PATH");
520
- }
488
+ startInstallerDetached(root, "hook: uv not on PATH");
489
+ uv = uvPath();
521
490
  if (!uv) {
522
- appendLog("backend.log", "[claude-smart] hook: uv not on PATH after installer; skipping");
491
+ appendLog("backend.log", "[claude-smart] hook: uv not on PATH; installer recovery scheduled; skipping");
523
492
  emitHookOk();
524
493
  return 0;
525
494
  }
@@ -190,14 +190,13 @@ case "$CMD" in
190
190
  NPM_BIN=$(claude_smart_resolve_npm || true)
191
191
  if [ -z "$NPM_BIN" ] || ! "$NPM_BIN" --version >/dev/null 2>&1; then
192
192
  if [ "${CLAUDE_SMART_BOOTSTRAPPING:-}" != "1" ] && [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
193
- echo "[claude-smart] dashboard: npm is not on PATH; running installer" >>"$LOG_FILE"
194
- CLAUDE_SMART_BOOTSTRAPPING=1 bash "$PLUGIN_ROOT/scripts/smart-install.sh" >>"$STATE_DIR/install.log" 2>&1 || true
195
- claude_smart_source_login_path
196
- claude_smart_prepend_node_bins
197
- NPM_BIN=$(claude_smart_resolve_npm || true)
193
+ echo "[claude-smart] dashboard: npm is not on PATH; starting installer in background" >>"$LOG_FILE"
194
+ claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
195
+ bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
196
+ >>"$STATE_DIR/install.log" 2>&1 || true
198
197
  fi
199
198
  if [ -z "$NPM_BIN" ] || ! "$NPM_BIN" --version >/dev/null 2>&1; then
200
- reason="npm is not on PATH after installer; dashboard cannot start"
199
+ reason="npm is not on PATH; installer recovery scheduled; dashboard cannot start yet"
201
200
  echo "[claude-smart] dashboard: $reason; skipping" >>"$LOG_FILE"
202
201
  claude_smart_write_dashboard_unavailable "$reason"
203
202
  emit_ok; exit 0
@@ -85,29 +85,18 @@ PY
85
85
  fi
86
86
 
87
87
  if ! command -v uv >/dev/null 2>&1; then
88
- # Self-heal from skipped Setup/SessionStart bootstrap. SessionStart can
89
- # afford to wait because it has the install budget; prompt/tool hooks start
90
- # the same installer detached so normal work is not blocked by first-run
91
- # dependency setup.
88
+ # Self-heal from skipped setup without blocking the first prompt. The
89
+ # installer and Setup hook own dependency bootstrap; hooks only schedule
90
+ # recovery and return so SessionStart stays lightweight.
92
91
  if [ "${CLAUDE_SMART_BOOTSTRAPPING:-}" = "1" ]; then
93
92
  claude_smart_emit_continue
94
93
  exit 0
95
94
  fi
96
95
  if [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
97
96
  mkdir -p "$STATE_DIR"
98
- if [ "$EVENT" = "session-start" ]; then
99
- CLAUDE_SMART_BOOTSTRAPPING=1 bash "$PLUGIN_ROOT/scripts/smart-install.sh" >&2
100
- claude_smart_prepend_astral_bins
101
- claude_smart_prepend_node_bins
102
- if command -v uv >/dev/null 2>&1; then
103
- bash "$HERE/backend-service.sh" start >/dev/null 2>&1 || true
104
- bash "$HERE/dashboard-service.sh" start >/dev/null 2>&1 || true
105
- fi
106
- else
107
- claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
108
- bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
109
- >>"$STATE_DIR/install.log" 2>&1 || true
110
- fi
97
+ claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
98
+ bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
99
+ >>"$STATE_DIR/install.log" 2>&1 || true
111
100
  fi
112
101
  if ! command -v uv >/dev/null 2>&1; then
113
102
  claude_smart_emit_continue
@@ -128,17 +117,13 @@ ensure_hook_package_importable() {
128
117
  fi
129
118
 
130
119
  mkdir -p "$STATE_DIR"
131
- if [ "$EVENT" = "session-start" ]; then
132
- CLAUDE_SMART_BOOTSTRAPPING=1 bash "$PLUGIN_ROOT/scripts/smart-install.sh" >&2
133
- else
134
- {
135
- printf '%s\n' "[claude-smart] hook: claude_smart.hook is not importable; retrying install in background"
136
- date 2>/dev/null || true
137
- } >>"$STATE_DIR/install.log" 2>&1
138
- claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
139
- bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
140
- >>"$STATE_DIR/install.log" 2>&1 || true
141
- fi
120
+ {
121
+ printf '%s\n' "[claude-smart] hook: claude_smart.hook is not importable; retrying install in background"
122
+ date 2>/dev/null || true
123
+ } >>"$STATE_DIR/install.log" 2>&1
124
+ claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
125
+ bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
126
+ >>"$STATE_DIR/install.log" 2>&1 || true
142
127
 
143
128
  claude_smart_python_imports "$PLUGIN_ROOT" claude_smart.hook
144
129
  }
@@ -118,6 +118,13 @@ install_complete() {
118
118
  return 0
119
119
  }
120
120
 
121
+ start_backend_service() {
122
+ if [ -x "$HERE/backend-service.sh" ]; then
123
+ echo "[claude-smart] starting backend service in background" >&2
124
+ bash "$HERE/backend-service.sh" start >/dev/null 2>&1 || true
125
+ fi
126
+ }
127
+
121
128
  install_vendored_reflexio() {
122
129
  local VENDORED_REFLEXIO PLUGIN_PYTHON
123
130
 
@@ -391,6 +398,7 @@ fi
391
398
  preflight_supported_runtime_platform
392
399
 
393
400
  if install_complete; then
401
+ start_backend_service
394
402
  claude_smart_emit_continue
395
403
  exit 0
396
404
  fi
@@ -624,6 +632,8 @@ if ! bash "$HERE/ensure-plugin-root.sh" "$PLUGIN_ROOT"; then
624
632
  echo "[claude-smart] WARNING: failed to set ~/.reflexio/plugin-root symlink — slash commands may not resolve" >&2
625
633
  fi
626
634
 
635
+ start_backend_service
636
+
627
637
  write_success_marker
628
- echo "[claude-smart] install complete. Backend and dashboard auto-start on session start." >&2
638
+ echo "[claude-smart] install complete. Backend started; dashboard auto-starts on session start." >&2
629
639
  claude_smart_emit_continue
package/plugin/uv.lock CHANGED
@@ -419,7 +419,7 @@ wheels = [
419
419
 
420
420
  [[package]]
421
421
  name = "claude-smart"
422
- version = "0.2.40"
422
+ version = "0.2.41"
423
423
  source = { editable = "." }
424
424
  dependencies = [
425
425
  { name = "chromadb" },