seif-cli 0.3.4__tar.gz → 0.3.5__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 (85) hide show
  1. {seif_cli-0.3.4/src/seif_cli.egg-info → seif_cli-0.3.5}/PKG-INFO +1 -1
  2. {seif_cli-0.3.4 → seif_cli-0.3.5}/pyproject.toml +1 -1
  3. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/bridge/native_client.py +71 -22
  4. {seif_cli-0.3.4 → seif_cli-0.3.5/src/seif_cli.egg-info}/PKG-INFO +1 -1
  5. {seif_cli-0.3.4 → seif_cli-0.3.5}/LICENSE +0 -0
  6. {seif_cli-0.3.4 → seif_cli-0.3.5}/MANIFEST.in +0 -0
  7. {seif_cli-0.3.4 → seif_cli-0.3.5}/README.md +0 -0
  8. {seif_cli-0.3.4 → seif_cli-0.3.5}/setup.cfg +0 -0
  9. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/__init__.py +0 -0
  10. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/__main__.py +0 -0
  11. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/analysis/__init__.py +0 -0
  12. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/analysis/physical_constants.py +0 -0
  13. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/analysis/quality_gate.py +0 -0
  14. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/analysis/stance_detector.py +0 -0
  15. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/analysis/transcompiler.py +0 -0
  16. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/bridge/__init__.py +0 -0
  17. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/bridge/telegram_bot.py +0 -0
  18. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/__init__.py +0 -0
  19. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/__main__.py +0 -0
  20. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/chat.py +0 -0
  21. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/cli.py +0 -0
  22. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/identity.py +0 -0
  23. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/main.py +0 -0
  24. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/resonance_display.py +0 -0
  25. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/serve.py +0 -0
  26. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/serve_v2.py +0 -0
  27. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/cli/wrapper.py +0 -0
  28. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/constants.py +0 -0
  29. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/__init__.py +0 -0
  30. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/advisor.py +0 -0
  31. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/code_compressor.py +0 -0
  32. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/context_bridge.py +0 -0
  33. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/context_importer.py +0 -0
  34. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/context_manager.py +0 -0
  35. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/context_qr.py +0 -0
  36. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/cycle.py +0 -0
  37. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/file_extractor.py +0 -0
  38. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/git_context.py +0 -0
  39. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/git_hooks.py +0 -0
  40. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/ingest.py +0 -0
  41. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/nucleus.py +0 -0
  42. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/ref.py +0 -0
  43. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/registry.py +0 -0
  44. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/seif_io.py +0 -0
  45. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/sessions.py +0 -0
  46. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/context/workspace.py +0 -0
  47. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/__init__.py +0 -0
  48. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/fingerprint.py +0 -0
  49. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/resonance_encoding.py +0 -0
  50. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/resonance_gate.py +0 -0
  51. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/resonance_signal.py +0 -0
  52. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/signing.py +0 -0
  53. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/timestamping.py +0 -0
  54. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/transfer_function.py +0 -0
  55. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/core/triple_gate.py +0 -0
  56. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/data/RESONANCE.json +0 -0
  57. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/data/__init__.py +0 -0
  58. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/data/defaults/__init__.py +0 -0
  59. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/data/paths.py +0 -0
  60. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/security/__init__.py +0 -0
  61. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif/security/mode.py +0 -0
  62. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif_cli.egg-info/SOURCES.txt +0 -0
  63. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif_cli.egg-info/dependency_links.txt +0 -0
  64. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif_cli.egg-info/entry_points.txt +0 -0
  65. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif_cli.egg-info/requires.txt +0 -0
  66. {seif_cli-0.3.4 → seif_cli-0.3.5}/src/seif_cli.egg-info/top_level.txt +0 -0
  67. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_advisor.py +0 -0
  68. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_canonical_inputs.py +0 -0
  69. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_code_compressor.py +0 -0
  70. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_collaborative_seif.py +0 -0
  71. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_context_qr.py +0 -0
  72. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_context_repo.py +0 -0
  73. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_git_context.py +0 -0
  74. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_git_hooks.py +0 -0
  75. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_init.py +0 -0
  76. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_quality_gate.py +0 -0
  77. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_ref.py +0 -0
  78. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_registry.py +0 -0
  79. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_resonance_gate.py +0 -0
  80. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_seif_io.py +0 -0
  81. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_stance_detector.py +0 -0
  82. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_transcompiler.py +0 -0
  83. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_transfer_function.py +0 -0
  84. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_triple_gate.py +0 -0
  85. {seif_cli-0.3.4 → seif_cli-0.3.5}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seif-cli
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: Measure AI output quality, protect sensitive data, watch your AI environment resonate. Quality Gate, Classification, Sentinel & Auto-Healing, SEIF OS.
5
5
  Author: André Cunha Antero de Carvalho
6
6
  License: CC-BY-NC-SA-4.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "seif-cli"
7
- version = "0.3.4"
7
+ version = "0.3.5"
8
8
  description = "Measure AI output quality, protect sensitive data, watch your AI environment resonate. Quality Gate, Classification, Sentinel & Auto-Healing, SEIF OS."
9
9
  readme = "README.md"
10
10
  license = {text = "CC-BY-NC-SA-4.0"}
@@ -1,18 +1,21 @@
1
1
  """
2
- Native AI Client — Direct SDK integration replacing CLI wrapper.
2
+ Native AI Client — Direct SDK integration with Claude CLI fallback.
3
3
 
4
4
  Supports streaming, multi-backend routing, and context injection from
5
- the personal nucleus. Falls back to CLI subprocess if SDK unavailable.
5
+ the personal nucleus. When no ANTHROPIC_API_KEY is set, uses Claude CLI
6
+ (compatible with Max Plan via OAuth).
6
7
  """
7
8
 
8
- from dataclasses import dataclass, field
9
+ from dataclasses import dataclass
9
10
  from typing import Iterator, Optional
10
11
  import os
12
+ import shutil
13
+ import subprocess
11
14
 
12
15
 
13
16
  @dataclass
14
17
  class ChatConfig:
15
- backend: str = "auto" # claude, gemini, local, auto
18
+ backend: str = "auto" # claude, claude-cli, gemini, local, auto
16
19
  model: str = "" # model override (empty = use default)
17
20
  stream: bool = True # streaming responses
18
21
  quality_gate: bool = True # measure every response
@@ -22,12 +25,17 @@ class ChatConfig:
22
25
  # Default models per backend
23
26
  _DEFAULT_MODELS = {
24
27
  "claude": "claude-sonnet-4-6",
28
+ "claude-cli": "claude-sonnet-4-6",
25
29
  "gemini": "gemini-2.5-flash",
26
30
  "grok": "grok-4-1-fast",
27
31
  "local": "llama3",
28
32
  }
29
33
 
30
34
 
35
+ def _has_claude_cli() -> bool:
36
+ return shutil.which("claude") is not None
37
+
38
+
31
39
  class NativeClient:
32
40
  """Multi-backend AI client with streaming support."""
33
41
 
@@ -48,8 +56,12 @@ class NativeClient:
48
56
  if profile_default and profile_default != "auto":
49
57
  return profile_default
50
58
 
59
+ # SDK requires API key with credits
51
60
  if os.environ.get("ANTHROPIC_API_KEY"):
52
61
  return "claude"
62
+ # No API key — prefer Claude CLI (Max Plan compatible)
63
+ if _has_claude_cli():
64
+ return "claude-cli"
53
65
  if os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY"):
54
66
  return "gemini"
55
67
  return "claude"
@@ -66,6 +78,8 @@ class NativeClient:
66
78
  """Send message and return complete response."""
67
79
  if self._backend == "claude":
68
80
  return self._send_claude(message, history or [], system)
81
+ elif self._backend == "claude-cli":
82
+ return self._send_claude_cli(message, history or [], system)
69
83
  elif self._backend == "gemini":
70
84
  return self._send_gemini(message, history or [], system)
71
85
  elif self._backend == "local":
@@ -75,12 +89,16 @@ class NativeClient:
75
89
 
76
90
  def stream(self, message: str, history: list[dict] = None,
77
91
  system: str = "") -> Iterator[str]:
78
- """Stream response tokens. Falls back to send() if streaming unavailable."""
92
+ """Stream response tokens."""
79
93
  if self._backend == "claude":
80
94
  yield from self._stream_claude(message, history or [], system)
95
+ elif self._backend == "claude-cli":
96
+ yield from self._stream_claude_cli(message, history or [], system)
81
97
  else:
82
98
  yield self.send(message, history, system)
83
99
 
100
+ # -- Claude SDK ------------------------------------------------
101
+
84
102
  def _send_claude(self, message: str, history: list[dict],
85
103
  system: str) -> str:
86
104
  try:
@@ -94,7 +112,7 @@ class NativeClient:
94
112
  )
95
113
  return response.content[0].text
96
114
  except ImportError:
97
- return self._fallback_cli(message, system)
115
+ return self._send_claude_cli(message, history, system)
98
116
  except Exception as e:
99
117
  return f"Error: {e}"
100
118
 
@@ -112,10 +130,54 @@ class NativeClient:
112
130
  for text in stream.text_stream:
113
131
  yield text
114
132
  except ImportError:
115
- yield self._fallback_cli(message, system)
133
+ yield from self._stream_claude_cli(message, history, system)
116
134
  except Exception as e:
117
135
  yield f"Error: {e}"
118
136
 
137
+ # -- Claude CLI (Max Plan) -------------------------------------
138
+
139
+ def _send_claude_cli(self, message: str, history: list[dict],
140
+ system: str) -> str:
141
+ try:
142
+ cmd = ["claude", "--print", "--output-format", "text",
143
+ "--no-session-persistence"]
144
+ if system:
145
+ cmd.extend(["--append-system-prompt", system])
146
+ cmd.append(message)
147
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
148
+ return result.stdout.strip() if result.returncode == 0 else f"CLI error: {result.stderr.strip()}"
149
+ except FileNotFoundError:
150
+ return "Claude CLI not found. Install: https://docs.anthropic.com/claude-code"
151
+ except subprocess.TimeoutExpired:
152
+ return "Claude CLI timeout (300s)."
153
+ except Exception as e:
154
+ return f"CLI error: {e}"
155
+
156
+ def _stream_claude_cli(self, message: str, history: list[dict],
157
+ system: str) -> Iterator[str]:
158
+ """Stream from Claude CLI via subprocess pipe."""
159
+ try:
160
+ cmd = ["claude", "--print", "--output-format", "text",
161
+ "--no-session-persistence"]
162
+ if system:
163
+ cmd.extend(["--append-system-prompt", system])
164
+ cmd.append(message)
165
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
166
+ stderr=subprocess.PIPE, text=True)
167
+ for line in proc.stdout:
168
+ yield line
169
+ proc.wait()
170
+ if proc.returncode != 0:
171
+ err = proc.stderr.read().strip()
172
+ if err:
173
+ yield f"\nCLI error: {err}"
174
+ except FileNotFoundError:
175
+ yield "Claude CLI not found. Install: https://docs.anthropic.com/claude-code"
176
+ except Exception as e:
177
+ yield f"CLI error: {e}"
178
+
179
+ # -- Gemini ----------------------------------------------------
180
+
119
181
  def _send_gemini(self, message: str, history: list[dict],
120
182
  system: str) -> str:
121
183
  try:
@@ -134,10 +196,11 @@ class NativeClient:
134
196
  except Exception as e:
135
197
  return f"Gemini error: {e}"
136
198
 
199
+ # -- Local (Ollama) --------------------------------------------
200
+
137
201
  def _send_local(self, message: str, history: list[dict],
138
202
  system: str) -> str:
139
203
  try:
140
- import subprocess
141
204
  result = subprocess.run(
142
205
  ["ollama", "run", self._model, message],
143
206
  capture_output=True, text=True, timeout=120,
@@ -147,17 +210,3 @@ class NativeClient:
147
210
  return "Ollama not installed. https://ollama.ai"
148
211
  except Exception as e:
149
212
  return f"Local error: {e}"
150
-
151
- def _fallback_cli(self, message: str, system: str) -> str:
152
- """Fall back to Claude CLI subprocess."""
153
- import subprocess
154
- try:
155
- cmd = ["claude", "--print", "--output-format", "text",
156
- "--no-session-persistence"]
157
- if system:
158
- cmd.extend(["--append-system-prompt", system])
159
- cmd.append(message)
160
- result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
161
- return result.stdout.strip() if result.returncode == 0 else f"CLI error: {result.stderr}"
162
- except FileNotFoundError:
163
- return "No AI backend available. Set ANTHROPIC_API_KEY or install claude CLI."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seif-cli
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: Measure AI output quality, protect sensitive data, watch your AI environment resonate. Quality Gate, Classification, Sentinel & Auto-Healing, SEIF OS.
5
5
  Author: André Cunha Antero de Carvalho
6
6
  License: CC-BY-NC-SA-4.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes