kader 0.1.0__py3-none-any.whl

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.
kader/tools/web.py ADDED
@@ -0,0 +1,246 @@
1
+ """
2
+ Web Tools for Agentic Operations.
3
+
4
+ Provides web search and fetch capabilities using Ollama's native API.
5
+ """
6
+
7
+ import json
8
+ from typing import Any
9
+
10
+ from .base import (
11
+ BaseTool,
12
+ ParameterSchema,
13
+ ToolCategory,
14
+ )
15
+
16
+ try:
17
+ import ollama
18
+ except ImportError:
19
+ ollama = None
20
+
21
+
22
+ class WebSearchTool(BaseTool[list[dict[str, Any]]]):
23
+ """
24
+ Tool to search the web using Ollama's search capability.
25
+ """
26
+
27
+ def __init__(self) -> None:
28
+ """Initialize the web search tool."""
29
+ super().__init__(
30
+ name="web_search",
31
+ description=(
32
+ "Search the web for information. Returns a list of relevant "
33
+ "results with titles, descriptions, and URLs."
34
+ ),
35
+ parameters=[
36
+ ParameterSchema(
37
+ name="query",
38
+ type="string",
39
+ description="Search query",
40
+ ),
41
+ ParameterSchema(
42
+ name="limit",
43
+ type="integer",
44
+ description="Number of results to return (max 10)",
45
+ required=False,
46
+ default=5,
47
+ minimum=1,
48
+ maximum=10,
49
+ ),
50
+ ],
51
+ category=ToolCategory.WEB,
52
+ )
53
+
54
+ def execute(self, query: str, limit: int = 5) -> list[dict[str, Any]]:
55
+ """
56
+ Execute web search.
57
+
58
+ Args:
59
+ query: Search query
60
+ limit: Number of results (default 5)
61
+
62
+ Returns:
63
+ """
64
+ if ollama is None:
65
+ raise ImportError(
66
+ "ollama is required for web tools. Install it with: uv add ollama"
67
+ )
68
+
69
+ try:
70
+ # Note: Ollama python lib uses 'limit' or just implicitly returns results
71
+ # The exact signature might vary as it's experimental, but based on docs:
72
+ # results = ollama.web_search(query=query)
73
+ # We'll try to slice manually if limit is not supported directly
74
+
75
+ # Using getattr to avoid static analysis errors if method is missing in older stub
76
+ search_func = getattr(ollama, "web_search", None)
77
+
78
+ if not search_func:
79
+ # Fallback or error if not available
80
+ # Assuming duckduckgo-search as fallback if allowed, but plan said Ollama first
81
+ # Let's check if we can import duckduckgo search as a robust fallback
82
+ # since "ollama.web_search" might be a hosted-only feature in some contexts.
83
+ # But per instruction, we use Ollama.
84
+
85
+ # If function is missing, raise clear error
86
+ raise NotImplementedError(
87
+ "ollama.web_search is not available in the installed library version. "
88
+ "Ensure 'ollama>=0.6.0' is installed."
89
+ )
90
+
91
+ # Execute search
92
+ response = search_func(query=query)
93
+
94
+ # Parse results
95
+ # Response might be a dict, an object with .results, or a list
96
+ results = []
97
+
98
+ if isinstance(response, dict):
99
+ results = response.get("results", [])
100
+ elif hasattr(response, "results"):
101
+ results = response.results
102
+ elif hasattr(response, "__dict__") and "results" in response.__dict__:
103
+ # Handle WebSearchResult object specifically
104
+ results = response.results
105
+ elif isinstance(response, list):
106
+ results = response
107
+ else:
108
+ # If it's some other object that behaves like a dict but failed above checks
109
+ try:
110
+ results = response["results"]
111
+ except (TypeError, KeyError, AttributeError):
112
+ # As a last resort, assume the response itself might be the iterable result
113
+ results = response
114
+
115
+ # Type check results to ensure it's a list (or iterable)
116
+ if not isinstance(results, list):
117
+ # Try to convert to list if it's iterable
118
+ try:
119
+ results = list(results)
120
+ except TypeError:
121
+ # If not iterable, wrap it or return empty
122
+ results = []
123
+
124
+ # Ensure results are JSON serializable
125
+ serializable_results = []
126
+ for item in results[:limit]:
127
+ if isinstance(item, (str, int, float, bool, type(None))):
128
+ serializable_results.append(item)
129
+ elif isinstance(item, dict):
130
+ # Ensure all dict values are serializable
131
+ serializable_dict = {}
132
+ for k, v in item.items():
133
+ try:
134
+ json.dumps(v) # Test if serializable
135
+ serializable_dict[k] = v
136
+ except TypeError:
137
+ serializable_dict[k] = str(
138
+ v
139
+ ) # Convert non-serializable to string
140
+ serializable_results.append(serializable_dict)
141
+ else:
142
+ # Convert any other type to string representation
143
+ serializable_results.append(str(item))
144
+
145
+ return serializable_results
146
+
147
+ except NotImplementedError:
148
+ raise
149
+ except Exception as e:
150
+ # Handle specific Ollama errors
151
+ raise RuntimeError(f"Web search failed: {str(e)}")
152
+
153
+ async def aexecute(self, query: str, limit: int = 5) -> list[dict[str, Any]]:
154
+ """Async version of execute."""
155
+ import asyncio
156
+
157
+ return await asyncio.to_thread(self.execute, query, limit)
158
+
159
+ def get_interruption_message(self, query: str, **kwargs) -> str:
160
+ """Get interruption message for user confirmation."""
161
+ return f"execute web_search: {query}"
162
+
163
+
164
+ class WebFetchTool(BaseTool[str]):
165
+ """
166
+ Tool to fetch and extract text content from a web page.
167
+ """
168
+
169
+ def __init__(self) -> None:
170
+ """Initialize the web fetch tool."""
171
+ super().__init__(
172
+ name="web_fetch",
173
+ description=(
174
+ "Fetch and extract readable text content from a URL. "
175
+ "Useful for reading documentation, articles, or web pages found via search."
176
+ ),
177
+ parameters=[
178
+ ParameterSchema(
179
+ name="url",
180
+ type="string",
181
+ description="URL of the page to fetch",
182
+ ),
183
+ ],
184
+ category=ToolCategory.WEB,
185
+ )
186
+
187
+ def execute(self, url: str) -> str:
188
+ """
189
+ Fetch web page content.
190
+
191
+ Args:
192
+ url: URL to fetch
193
+
194
+ Returns:
195
+ Extracted text content
196
+ """
197
+ if ollama is None:
198
+ raise ImportError(
199
+ "ollama is required for web tools. Install it with: uv add ollama"
200
+ )
201
+
202
+ try:
203
+ fetch_func = getattr(ollama, "web_fetch", None)
204
+
205
+ if not fetch_func:
206
+ raise NotImplementedError(
207
+ "ollama.web_fetch is not available in the installed library version."
208
+ )
209
+
210
+ response = fetch_func(url=url)
211
+
212
+ # Return content (assuming response implies content string or dict with content)
213
+ if isinstance(response, dict):
214
+ content = response.get("content", str(response))
215
+ else:
216
+ content = str(response)
217
+
218
+ # Ensure the content is JSON serializable
219
+ try:
220
+ json.dumps(content) # Test if serializable
221
+ return content
222
+ except TypeError:
223
+ return str(content) # Convert non-serializable to string
224
+
225
+ except NotImplementedError:
226
+ raise
227
+ except Exception as e:
228
+ raise RuntimeError(f"Web fetch failed: {str(e)}")
229
+
230
+ async def aexecute(self, url: str) -> str:
231
+ """Async version of execute."""
232
+ import asyncio
233
+
234
+ return await asyncio.to_thread(self.execute, url)
235
+
236
+ def get_interruption_message(self, url: str, **kwargs) -> str:
237
+ """Get interruption message for user confirmation."""
238
+ return f"execute web_fetch: {url}"
239
+
240
+
241
+ def get_web_tools() -> list[BaseTool]:
242
+ """Get all web tools."""
243
+ return [
244
+ WebSearchTool(),
245
+ WebFetchTool(),
246
+ ]
@@ -0,0 +1,319 @@
1
+ Metadata-Version: 2.4
2
+ Name: kader
3
+ Version: 0.1.0
4
+ Summary: kader coding agent
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: faiss-cpu>=1.9.0
7
+ Requires-Dist: loguru>=0.7.3
8
+ Requires-Dist: ollama>=0.6.1
9
+ Requires-Dist: pyyaml>=6.0.3
10
+ Requires-Dist: tenacity>=9.1.2
11
+ Requires-Dist: textual[syntax]>=6.8.0
12
+ Requires-Dist: typing-extensions>=4.15.0
13
+ Requires-Dist: wcmatch>=10.1
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Kader
17
+
18
+ Kader is an intelligent coding agent designed to assist with software development tasks. It provides a comprehensive framework for building AI-powered agents with advanced reasoning capabilities and tool integration.
19
+
20
+ ## Features
21
+
22
+ - 🤖 **AI-powered Code Assistance** - Using Ollama for local LLM execution
23
+ - 🖥️ **Interactive CLI** - Modern TUI interface built with Textual
24
+ - 🛠️ **Tool Integration** - File system, command execution, web search, and more
25
+ - 🧠 **Memory Management** - State persistence and conversation history
26
+ - 🔁 **Session Management** - Save and load conversation sessions
27
+ - 🎨 **Theming** - Multiple color themes for the CLI interface
28
+ - ⌨️ **Keyboard Shortcuts** - Efficient navigation and operations
29
+ - 📝 **YAML Configuration** - Agent configuration via YAML files
30
+ - 🔄 **ReAct Agent Framework** - Reasoning and Acting agent architecture
31
+ - 🗂️ **File System Tools** - Read, write, search, and edit files
32
+ - 🔍 **Planning Agent** - Task planning and execution capabilities
33
+
34
+ ## Installation
35
+
36
+ ### Prerequisites
37
+
38
+ - Python 3.11 or higher
39
+ - [Ollama](https://ollama.ai/) running locally to use LLMs
40
+ - [uv](https://docs.astral.sh/uv/) package manager (recommended) or [pip](https://pypi.org/project/pip/)
41
+
42
+ ### Using uv (recommended)
43
+
44
+ ```bash
45
+ # Clone the repository
46
+ git clone https://github.com/your-repo/kader.git
47
+ cd kader
48
+
49
+ # Install dependencies with uv
50
+ uv sync
51
+
52
+ # Run the CLI
53
+ uv run python -m cli
54
+ ```
55
+
56
+ ### Using pip
57
+
58
+ ```bash
59
+ # Clone the repository
60
+ git clone https://github.com/your-repo/kader.git
61
+ cd kader
62
+
63
+ # Install in development mode
64
+ pip install -e .
65
+
66
+ # Run the CLI
67
+ python -m cli
68
+ ```
69
+
70
+ ## Quick Start
71
+
72
+ ### Running the CLI
73
+
74
+ ```bash
75
+ # Run the Kader CLI using uv
76
+ uv run python -m cli
77
+
78
+ # Or using pip
79
+ python -m cli
80
+ ```
81
+
82
+ ### First Steps in CLI
83
+
84
+ Once the CLI is running:
85
+
86
+ 1. Type any question to start chatting with the agent
87
+ 2. Use `/help` to see available commands
88
+ 3. Use `/models` to check available models
89
+ 4. Use `/theme` to cycle through color themes
90
+
91
+ ## Configuration
92
+
93
+ When the kader module is imported for the first time, it automatically:
94
+ 1. Creates a `.kader` directory in your home directory (`~/.kader` on Unix systems, `%USERPROFILE%\.kader` on Windows)
95
+ 2. Creates a `.env` file with the required configuration (including `OLLAMA_API_KEY=''`)
96
+ 3. Loads all environment variables from the `.env` file into the application environment
97
+
98
+ ### Environment Variables
99
+
100
+ The application automatically loads environment variables from `~/.kader/.env`:
101
+ - `OLLAMA_API_KEY`: API key for Ollama service (default: empty)
102
+ - Additional variables can be added to the `.env` file and will be automatically loaded
103
+
104
+ ### Memory and Sessions
105
+
106
+ Kader stores data in `~/.kader/`:
107
+ - Sessions: `~/.kader/sessions/`
108
+ - Configuration: `~/.kader/`
109
+ - Memory files: `~/.kader/memory/`
110
+
111
+ ## CLI Commands
112
+
113
+ | Command | Description |
114
+ |---------|-------------|
115
+ | `/help` | Show command reference |
116
+ | `/models` | Show available Ollama models |
117
+ | `/theme` | Cycle color themes |
118
+ | `/clear` | Clear conversation |
119
+ | `/save` | Save current session |
120
+ | `/load <id>` | Load a saved session |
121
+ | `/sessions` | List saved sessions |
122
+ | `/refresh` | Refresh file tree |
123
+ | `/exit` | Exit the CLI |
124
+
125
+ ### Keyboard Shortcuts
126
+
127
+ | Shortcut | Action |
128
+ |----------|--------|
129
+ | `Ctrl+Q` | Quit |
130
+ | `Ctrl+L` | Clear conversation |
131
+ | `Ctrl+T` | Cycle theme |
132
+ | `Ctrl+S` | Save session |
133
+ | `Ctrl+R` | Refresh file tree |
134
+ | `Tab` | Navigate panels |
135
+
136
+ ## Project Structure
137
+
138
+ ```
139
+ kader/
140
+ ├── cli/ # Interactive command-line interface
141
+ │ ├── app.py # Main application entry point
142
+ │ ├── app.tcss # Textual CSS for styling
143
+ │ ├── utils.py # Utility functions and constants
144
+ │ ├── widgets/ # Custom Textual widgets
145
+ │ │ ├── conversation.py # Chat display widget
146
+ │ │ ├── loading.py # Loading spinner widget
147
+ │ │ └── confirmation.py # Tool/model selection widgets
148
+ │ └── README.md # CLI documentation
149
+ ├── examples/ # Example implementations
150
+ │ ├── memory_example.py # Memory management examples
151
+ │ ├── ollama_example.py # Ollama provider examples
152
+ │ ├── react_agent_example.py # ReAct agent examples
153
+ │ ├── planning_agent_example.py # Planning agent examples
154
+ │ ├── python_developer/ # Python expert agent example
155
+ │ ├── todo_agent/ # Todo management agent example
156
+ │ └── README.md # Examples documentation
157
+ ├── kader/ # Core framework
158
+ │ ├── agent/ # Agent implementations
159
+ │ ├── memory/ # Memory management
160
+ │ ├── providers/ # LLM providers
161
+ │ ├── tools/ # Tools and utilities
162
+ │ └── prompts/ # Prompt templates
163
+ ├── pyproject.toml # Project dependencies
164
+ ├── README.md # This file
165
+ └── uv.lock # Dependency lock file
166
+ ```
167
+
168
+ ## Core Components
169
+
170
+ ### Agents
171
+
172
+ Kader provides several agent types:
173
+
174
+ - **ReActAgent**: Reasoning and Acting agent that combines thoughts with actions
175
+ - **PlanningAgent**: Agent that plans multi-step tasks
176
+ - **BaseAgent**: Base agent class for creating custom agents
177
+
178
+ ### Memory Management
179
+
180
+ Kader's memory system includes:
181
+
182
+ - **AgentState**: Persistent key-value storage for agents
183
+ - **RequestState**: Ephemeral request-scoped state
184
+ - **FileSessionManager**: Session persistence to disk
185
+ - **SlidingWindowConversationManager**: Conversation windowing
186
+
187
+ ### Tools
188
+
189
+ Kader includes a rich set of tools:
190
+
191
+ - **File System Tools**: Read, write, edit, search files
192
+ - **Command Executor**: Execute shell commands safely
193
+ - **Web Tools**: Search and fetch web content
194
+ - **RAG Tools**: Retrieval Augmented Generation capabilities
195
+
196
+ ## Examples
197
+
198
+ Check out the examples directory for comprehensive demonstrations of Kader's features:
199
+
200
+ ### Basic Examples
201
+
202
+ - `memory_example.py`: Shows memory management capabilities
203
+ - `ollama_example.py`: Demonstrates how to use the Ollama provider for LLM interactions
204
+ - `tools_example.py`: Demonstrates the various tools available in Kader
205
+ - `simple_agent.py`: Basic agent implementation example
206
+
207
+ ### Advanced Examples
208
+
209
+ - `react_agent_example.py`: Interactive ReAct agent with tool integration
210
+ - `planning_agent_example.py`: Planning agent for multi-step tasks
211
+ - `python_developer/`: Specialized Python expert agent (YAML-configured)
212
+ - `todo_agent/`: Task management agent with TodoTool
213
+
214
+ ### Running Examples
215
+
216
+ Use uv to run examples:
217
+
218
+ ```bash
219
+ uv run python -m examples.memory_example
220
+ uv run python -m examples.ollama_example
221
+ uv run python -m examples.tools_example
222
+ uv run python -m examples.react_agent_example
223
+ uv run python -m examples.python_developer.main
224
+ uv run python -m examples.todo_agent.main
225
+ ```
226
+
227
+ ## Architecture
228
+
229
+ ### Agent Architecture
230
+
231
+ Kader uses a modular architecture where:
232
+
233
+ 1. **Agents** define the behavior and reasoning strategy
234
+ 2. **Tools** provide capabilities for external interactions
235
+ 3. **Memory** manages state and conversation history
236
+ 4. **Providers** handle LLM interactions
237
+
238
+ ### Tool Architecture
239
+
240
+ Tools in Kader follow a standardized interface:
241
+
242
+ - Each tool has a schema defining its inputs and outputs
243
+ - Tools can be registered in a ToolRegistry
244
+ - Tools can be executed synchronously or asynchronously
245
+ - Tools can be configured with parameters
246
+
247
+ ## Development
248
+
249
+ ### Setting up for Development
250
+
251
+ ```bash
252
+ # Clone the repository
253
+ git clone https://github.com/your-repo/kader.git
254
+ cd kader
255
+
256
+ # Install in development mode with uv
257
+ uv sync
258
+
259
+ # Run the CLI with hot reload for development
260
+ uv run textual run --dev cli.app:KaderApp
261
+ ```
262
+
263
+ ### Running Tests
264
+
265
+ ```bash
266
+ # Run tests with uv
267
+ uv run pytest
268
+
269
+ # Run tests with specific options
270
+ uv run pytest --verbose
271
+ ```
272
+
273
+ ### Code Quality
274
+
275
+ Kader uses various tools for maintaining code quality:
276
+
277
+ ```bash
278
+ # Run linter
279
+ uv run ruff check .
280
+
281
+ # Format code
282
+ uv run ruff format .
283
+ ```
284
+
285
+ ## Troubleshooting
286
+
287
+ ### Common Issues
288
+
289
+ - **No models found**: Make sure Ollama is running and you have at least one model installed (e.g., `ollama pull gpt-oss:120b-cloud`)
290
+ - **Connection errors**: Verify that Ollama service is accessible at the configured endpoint
291
+ - **Theme not changing**: Some terminal emulators may not support all color themes
292
+
293
+ ### Debugging
294
+
295
+ If you encounter issues:
296
+
297
+ 1. Check that Ollama is running: `ollama serve`
298
+ 2. Verify your model is pulled: `ollama list`
299
+ 3. Ensure your terminal supports the required features
300
+ 4. Check the logs for specific error messages
301
+
302
+ ## Contributing
303
+
304
+ 1. Fork the repository
305
+ 2. Create a feature branch
306
+ 3. Make your changes
307
+ 4. Add tests if applicable
308
+ 5. Run the test suite
309
+ 6. Submit a pull request
310
+
311
+ ## License
312
+
313
+ This project is licensed under the MIT License - see the LICENSE file for details.
314
+
315
+ ## Acknowledgments
316
+
317
+ - Built with [Textual](https://textual.textualize.io/) for the beautiful CLI interface
318
+ - Uses [Ollama](https://ollama.ai/) for local LLM execution
319
+ - Inspired by ReAct (Reasoning and Acting) agent architecture
@@ -0,0 +1,45 @@
1
+ cli/README.md,sha256=DY3X7w6LPka1GzhtTrGwhpkFmx0YyRpcTCHjFmti3Yg,4654
2
+ cli/__init__.py,sha256=OAi_KSwcuYXR0sRxKuw1DYQrz1jbu8p7vn41_99f36I,107
3
+ cli/__main__.py,sha256=xO2JVjCsh691b-cjSBAEKocJeUeI3P0gfUqM-f1Mp1A,95
4
+ cli/app.py,sha256=eEWrfq_XobsjAeSc2lRMNBJ1cs2nlZ_qeoamuqSnubg,19981
5
+ cli/app.tcss,sha256=eJX5akeqHmoZVDjibvBPIBot5UK7eiUxgojNu9IjMBs,10098
6
+ cli/utils.py,sha256=jt5wvSMIjPP-ZbvXEK2fd00-oRj32sj95HinJd4c73Q,1815
7
+ cli/widgets/__init__.py,sha256=1vj31CrJyxZROLthkKr79i_GbNyj8g3q60ZQPbJHK5k,300
8
+ cli/widgets/confirmation.py,sha256=s6h3ZY98xHeeF3G-OtHYYw-xPlAP6K7i73jo_ftOMQc,9400
9
+ cli/widgets/conversation.py,sha256=vqI3eq7qQrn4UD8fB8rBr33kIesrLpNVhNIp3MdGeOM,1519
10
+ cli/widgets/loading.py,sha256=xME_riHCJ0smN9Fo-usa45WEfGLmkdcf9ntMqnZAztA,1703
11
+ kader/__init__.py,sha256=QXb0aQvySAiNmhP2kNMNtuuzG_eSUgRVcTRSafko1r0,602
12
+ kader/config.py,sha256=B1s1PNgZ5SrFEJU5TtJG-ZAc7Umff4cwyHR7mfQgeLA,4261
13
+ kader/agent/__init__.py,sha256=UJzUw9NIzggCrhIBHC6nJnfzkhCjCZnIzmD6uUn2SNA,159
14
+ kader/agent/agents.py,sha256=lo41hlkPm3CStI9VAwSOR6IYhCBkqQJ48Ego5XN1XU8,4299
15
+ kader/agent/base.py,sha256=qWT53Fuw3I61X9wvZFDNJ8YnYSxBJKdnOH1122cWP2s,36452
16
+ kader/agent/logger.py,sha256=Y8Ig6Jab_jEDUCStAnv-zmBf8u7Ubpe5ry-zaPmj0Kk,6582
17
+ kader/memory/__init__.py,sha256=VUzzhGOWvO_2aYB6uuavmtNI8l94K7H3uPn4_1MVUUs,1473
18
+ kader/memory/conversation.py,sha256=h6Bamd8_rYnk0Bwt4MJWZRfv2wxCcg6eUxPvzP-tIyA,11810
19
+ kader/memory/session.py,sha256=VhRPEO474SlwM5UOuFt-b_28sJs3j4SNrobCZvoP5Os,10811
20
+ kader/memory/state.py,sha256=itwRjA4PvLlqlRStu-PnMWgSNsMTeU7R0qPOuj0mVDM,5722
21
+ kader/memory/types.py,sha256=h8B40dupNHNZgYC9WJ4hArnlUbX28Pv-XtgIcfUeqQw,3338
22
+ kader/prompts/__init__.py,sha256=TS1kYmEX6TkZcB9GDiulZLI0i9RvFuqMR_kPZEn7AZU,230
23
+ kader/prompts/agent_prompts.py,sha256=Gn3LKPlVLNy3JMWmtv4jcGr5jXu_YcR-0Y4qHjq-Y_s,809
24
+ kader/prompts/base.py,sha256=mFfPfuTX7VNjjiBqez10S7oxyNpiw9U63hTVVAPmlKY,2387
25
+ kader/prompts/templates/planning_agent.j2,sha256=Uc4SnMPv4vKWchhO0RLRNjbEio5CVlRgqDJG_dgM2Pk,1315
26
+ kader/prompts/templates/react_agent.j2,sha256=yME6Qgj2WTW8jRZ_yuQcY6xlXKcV7YUv5sz5ZfCl8P4,606
27
+ kader/providers/__init__.py,sha256=DYEZakt2SRy0Xd2vem93V_TRlY2s19KaJC9bSaOB1WY,154
28
+ kader/providers/base.py,sha256=gxpomjRAX9q3Qf4GHYxdiGI_GsRW9BG7PM38SKUAeCk,17105
29
+ kader/providers/mock.py,sha256=VBuOFFPvDWn4QVFS9HXlwu3jswP0NNNxrMyL4Qgvm50,2723
30
+ kader/providers/ollama.py,sha256=lTuwzFFPMmlD5xBhK_mYG2AvTA0-OLcPDfPwc3lLkTQ,15557
31
+ kader/tools/README.md,sha256=lmw-Ghm8ie2pNcSTL4sJ7OKerkGvbXmlD9Zi87hiC-8,14347
32
+ kader/tools/__init__.py,sha256=6h4Tif5VcYyaL18b_feM91LEF_9nXqcaQwaQ920wRI0,2527
33
+ kader/tools/base.py,sha256=oHqY1-5ihcH4ilvuHd-c5Vb81xm3jAlMrkRlR_8wltE,28840
34
+ kader/tools/exec_commands.py,sha256=nRKkV84Q8b9kHn8vSIKYe6eKhLx9pGRL-5C1hC11-7Y,7948
35
+ kader/tools/filesys.py,sha256=offjTGg1cOolwAGnGnnKguh3225tbVUUu-ipJ2TpaC8,19570
36
+ kader/tools/filesystem.py,sha256=ANTyiFgdxvYSWbp-hSH0AxGH_x-gx2V6XwYypE2MtoM,22733
37
+ kader/tools/protocol.py,sha256=xyLc-5xY1f9VvumnruoJpLldRk3vzDi1WEDcYXgH7o4,15825
38
+ kader/tools/rag.py,sha256=37Nd49D5R_DlWmMyhSdSvst_XFOnoxpaFNtlbLEt6qM,15653
39
+ kader/tools/todo.py,sha256=omirxoG7_KVHAmMoD12DGmn7scqRaewbI1cqWm0ShUo,7735
40
+ kader/tools/utils.py,sha256=bfq7b1vpA1qBaL_QZYBFTqOM35-omu_UeDjo6v0rxEg,14176
41
+ kader/tools/web.py,sha256=2Aqy0nO7ZwNLAqE9IWjCg5y8qnhbt-AIZOHy02XgbxA,8464
42
+ kader-0.1.0.dist-info/METADATA,sha256=J_DfNeYzT6xLF8XAv4CB6UC2s_niBJ4zHznt8g0VEOk,9461
43
+ kader-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
44
+ kader-0.1.0.dist-info/entry_points.txt,sha256=TK0VOtrfDFqZ8JQfxpuAHHvDLHyoiafUjS-VOixl02c,39
45
+ kader-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ kader = cli.app:main