makeless 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.
agent/planner.py ADDED
@@ -0,0 +1,11 @@
1
+
2
+ from abc import ABC, abstractmethod
3
+
4
+ from agent.state import AgentAction, AgentState
5
+
6
+
7
+ class Planner(ABC):
8
+
9
+ @abstractmethod
10
+ def plan(self, state: AgentState) -> AgentAction:
11
+ pass
agent/runtime.py ADDED
File without changes
agent/state.py ADDED
@@ -0,0 +1,40 @@
1
+
2
+ from dataclasses import dataclass, field
3
+ from enum import Enum
4
+ from typing import Any
5
+
6
+
7
+ class AgentStatus(Enum):
8
+ IDLE = "idle"
9
+ RUNNING = "running"
10
+ COMPLETED = "completed"
11
+ FAILED = "failed"
12
+ WAITING = "waiting"
13
+
14
+
15
+ class ActionType(Enum):
16
+ CALL_TOOL = "call_tool"
17
+ FINISH = "finish"
18
+
19
+
20
+ @dataclass
21
+ class AgentAction:
22
+ action_type: ActionType
23
+ tool_name: str | None = None
24
+ arguments: dict[str, Any] = field(default_factory=dict)
25
+
26
+
27
+ @dataclass
28
+ class ToolResult:
29
+ success: bool
30
+ output: Any = None
31
+ error: str | None = None
32
+
33
+
34
+ @dataclass
35
+ class AgentState:
36
+ task: str
37
+ status: AgentStatus = AgentStatus.IDLE
38
+ step_count: int = 0
39
+ max_steps: int = 10
40
+ history: list[dict[str, Any]] = field(default_factory=list)
app/main.py ADDED
File without changes
execution/executor.py ADDED
File without changes
main.py ADDED
@@ -0,0 +1,272 @@
1
+ from tools.filesystem import search_files
2
+ from tools.watcher import start_watcher
3
+ from tools.locations import get_system_location
4
+ from tools.reader import read_file
5
+ from tools.selector import select_result
6
+ from tools.open_router import open_item
7
+ from tools.app_finder import find_apps
8
+ from tools.app_launcher import launch_app
9
+ from tools.launcher import search_in_browser
10
+
11
+
12
+ def choose_path(query):
13
+ """
14
+ Search for an item and let the user choose if
15
+ multiple matches are found.
16
+ """
17
+
18
+ results = search_files(query, max_results=10)
19
+
20
+ if not results:
21
+ return None
22
+
23
+ if len(results) == 1:
24
+ return results[0]
25
+
26
+ return select_result(results)
27
+
28
+
29
+ def choose_app(apps):
30
+ """
31
+ Choose an application from search results.
32
+ """
33
+
34
+ if len(apps) == 1:
35
+ return apps[0]
36
+
37
+ app_paths = []
38
+
39
+ for app in apps:
40
+ app_paths.append(app["path"])
41
+
42
+ selected_path = select_result(app_paths)
43
+
44
+ if not selected_path:
45
+ return None
46
+
47
+ for app in apps:
48
+ if app["path"] == selected_path:
49
+ return app
50
+
51
+ return None
52
+
53
+
54
+ def handle_instruction(instruction):
55
+ instruction = instruction.strip()
56
+ lower_instruction = instruction.casefold()
57
+
58
+ # Read a file.
59
+ if lower_instruction.startswith("read "):
60
+ query = instruction[5:].strip()
61
+
62
+ if not query:
63
+ print("AgentCore: Tell me what you want me to read.")
64
+ return
65
+
66
+ print(f"\nAgentCore: Looking for '{query}'...")
67
+
68
+ path = choose_path(query)
69
+
70
+ if not path:
71
+ print("AgentCore: I couldn't find that file.")
72
+ return
73
+
74
+ success, content = read_file(path)
75
+
76
+ if not success:
77
+ print(f"AgentCore: {content}")
78
+ return
79
+
80
+ print("\n" + "=" * 50)
81
+ print(f"READING: {path}")
82
+ print("=" * 50 + "\n")
83
+
84
+ print(content)
85
+
86
+ print("\n" + "=" * 50)
87
+ print("End of file.")
88
+ print("=" * 50)
89
+
90
+ return
91
+
92
+ # Find files and folders.
93
+ if lower_instruction.startswith("find "):
94
+ query = instruction[5:].strip()
95
+
96
+ if not query:
97
+ print("AgentCore: Tell me what you want to find.")
98
+ return
99
+
100
+ print(f"\nAgentCore: Searching for '{query}'...\n")
101
+
102
+ results = search_files(query)
103
+
104
+ if not results:
105
+ print("AgentCore: Nothing found.")
106
+ return
107
+
108
+ print(f"AgentCore: Found {len(results)} result(s).")
109
+
110
+ for index, result in enumerate(results, start=1):
111
+ print(f"{index}. {result}")
112
+
113
+ return
114
+
115
+ # Open a browser and search the web.
116
+ separator = " and search for "
117
+
118
+ if (
119
+ lower_instruction.startswith("open ")
120
+ and separator in lower_instruction
121
+ ):
122
+ split_index = lower_instruction.index(separator)
123
+
124
+ browser_name = instruction[5:split_index].strip()
125
+ search_query = instruction[split_index + len(separator):].strip()
126
+
127
+ if not browser_name:
128
+ print("AgentCore: Tell me which browser to use.")
129
+ return
130
+
131
+ if not search_query:
132
+ print("AgentCore: Tell me what you want to search for.")
133
+ return
134
+
135
+ print(
136
+ f"\nAgentCore: Searching for "
137
+ f"'{search_query}' in {browser_name.title()}..."
138
+ )
139
+
140
+ success, message = search_in_browser(
141
+ search_query,
142
+ browser_name
143
+ )
144
+
145
+ print(f"AgentCore: {message}")
146
+ return
147
+
148
+ # Open something in a specific application.
149
+ if (
150
+ lower_instruction.startswith("open ")
151
+ and (
152
+ lower_instruction.endswith(" in vs code")
153
+ or lower_instruction.endswith(" in vscode")
154
+ )
155
+ ):
156
+ if lower_instruction.endswith(" in vs code"):
157
+ query = instruction[5:-11].strip()
158
+ else:
159
+ query = instruction[5:-10].strip()
160
+
161
+ if not query:
162
+ print("AgentCore: Tell me what you want to open.")
163
+ return
164
+
165
+ print(f"\nAgentCore: Looking for '{query}'...")
166
+
167
+ system_location = get_system_location(query)
168
+
169
+ if system_location:
170
+ path = str(system_location)
171
+ else:
172
+ path = choose_path(query)
173
+
174
+ if not path:
175
+ print("AgentCore: I couldn't find that.")
176
+ return
177
+
178
+ success, message = open_item(
179
+ path,
180
+ app="vscode"
181
+ )
182
+
183
+ print(f"AgentCore: {message}")
184
+ return
185
+
186
+ # Open something normally.
187
+ if lower_instruction.startswith("open "):
188
+ query = instruction[5:].strip()
189
+
190
+ if not query:
191
+ print("AgentCore: Tell me what you want to open.")
192
+ return
193
+
194
+ print(f"\nAgentCore: Looking for '{query}'...")
195
+
196
+ # 1. Check known locations first.
197
+ system_location = get_system_location(query)
198
+
199
+ if system_location:
200
+ path = str(system_location)
201
+ else:
202
+ # 2. Check installed apps.
203
+ apps = find_apps(query)
204
+
205
+ if apps:
206
+ app = choose_app(apps)
207
+
208
+ if app:
209
+ success, message = launch_app(
210
+ app["path"]
211
+ )
212
+
213
+ if success:
214
+ print(
215
+ f"AgentCore: Launched {app['name']}"
216
+ )
217
+ else:
218
+ print(f"AgentCore: {message}")
219
+
220
+ return
221
+
222
+ # 3. Otherwise search files.
223
+ path = choose_path(query)
224
+
225
+ if not path:
226
+ print("AgentCore: I couldn't find that.")
227
+ return
228
+
229
+ success, message = open_item(path)
230
+
231
+ print(f"AgentCore: {message}")
232
+ return
233
+
234
+ print("AgentCore: I don't know how to perform that task yet.")
235
+
236
+
237
+ def main():
238
+ print("================================")
239
+ print(" AgentCore Local")
240
+ print("================================")
241
+ print("Starting local computer operator...")
242
+
243
+ observer = start_watcher()
244
+
245
+ print("\nReady.")
246
+ print("Tell me what you want to do.")
247
+ print("Type 'exit' to close.\n")
248
+
249
+ try:
250
+ while True:
251
+ instruction = input("You: ")
252
+
253
+ if instruction.strip().casefold() == "exit":
254
+ print("\nAgentCore: Shutting down...")
255
+ break
256
+
257
+ if not instruction.strip():
258
+ continue
259
+
260
+ handle_instruction(instruction)
261
+
262
+ except KeyboardInterrupt:
263
+ print("\n\nAgentCore: Interrupted. Shutting down...")
264
+
265
+ finally:
266
+ observer.stop()
267
+ observer.join()
268
+ print("AgentCore: Goodbye!")
269
+
270
+
271
+ if __name__ == "__main__":
272
+ main()
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: makeless
3
+ Version: 0.1.0
4
+ Summary: A local-first computer operator for Windows.
5
+ Author: Avinash
6
+ License: Copyright (c) 2026 Avinash
7
+ Project-URL: Homepage, https://github.com/kkj4u2t7/agentcore
8
+ Project-URL: Repository, https://github.com/kkj4u2t7/agentcore
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: watchdog
13
+ Dynamic: license-file
14
+
15
+ # AgentCore
16
+
17
+ A local-first computer operator for Windows.
18
+
19
+ AgentCore lets you interact with your computer using simple, natural language commands. It can find files, open folders, read files, launch applications, and search the web.
20
+
21
+ ## Features
22
+
23
+ - 🔍 Fast file and folder search using a local index
24
+ - ⚡ Live file watching for common user folders
25
+ - 📂 Open files and folders
26
+ - 📖 Read text-based files directly in the terminal
27
+ - 💻 Open files and folders in VS Code
28
+ - 🚀 Find and launch installed applications
29
+ - 🌐 Search the web using your preferred browser
30
+ - 🗣️ Simple natural language commands
31
+
32
+ ## Examples
33
+
34
+ ```text
35
+ Find mypanpic
36
+ Open mypanpic
37
+ Read main.py
38
+ Open agentcore in VS Code
39
+ Open Chrome
40
+ Open Chrome and search for committ.in
41
+ ```
42
+
43
+ ## Installation
44
+
45
+ ### Clone the repository
46
+
47
+ ```bash
48
+ git clone https://github.com/kkj4u2t7/agentcore.git
49
+ cd agentcore
50
+ ```
51
+
52
+ ### Create a virtual environment
53
+
54
+ ```bash
55
+ python -m venv .venv
56
+ ```
57
+
58
+ Activate it on Windows:
59
+
60
+ ```powershell
61
+ .venv\Scripts\Activate.ps1
62
+ ```
63
+
64
+ ### Install dependencies
65
+
66
+ ```bash
67
+ pip install -r requirements.txt
68
+ ```
69
+
70
+ ### Run AgentCore
71
+
72
+ ```bash
73
+ python main.py
74
+ ```
75
+
76
+ ## How It Works
77
+
78
+ AgentCore uses a local file index to make searching faster than scanning your entire computer every time.
79
+
80
+ ```text
81
+ Your instruction
82
+ ↓
83
+ Command interpretation
84
+ ↓
85
+ File / App / Browser routing
86
+ ↓
87
+ Local computer action
88
+ ```
89
+
90
+ The file watcher keeps the index updated when files are added or changed in watched locations.
91
+
92
+ ## Project Structure
93
+
94
+ ```text
95
+ agentcore/
96
+ ├── tools/ # Computer interaction tools
97
+ ├── agent/ # Agent runtime components
98
+ ├── tests/ # Tests
99
+ ├── data/ # Local data, not committed to Git
100
+ ├── main.py # Application entry point
101
+ └── requirements.txt
102
+ ```
103
+
104
+ ## Roadmap
105
+
106
+ - [x] Fast indexed file search
107
+ - [x] Live file watching
108
+ - [x] Open files and folders
109
+ - [x] Read files from the terminal
110
+ - [x] Launch installed applications
111
+ - [x] Browser web search
112
+ - [ ] More natural language commands
113
+ - [ ] Command history
114
+ - [ ] Safer action confirmation
115
+ - [ ] Cross-platform support
116
+ - [ ] AI-powered command understanding
117
+
118
+ ## Contributing
119
+
120
+ Contributions, ideas, and bug reports are welcome.
121
+
122
+ 1. Fork the repository
123
+ 2. Create a feature branch
124
+ 3. Make your changes
125
+ 4. Submit a Pull Request
126
+
127
+ ## License
128
+
129
+ This project is licensed under the MIT License.
130
+
131
+ ## Author
132
+
133
+ Created and maintained by **Avinash**.
@@ -0,0 +1,28 @@
1
+ main.py,sha256=LUyJinTGmExnL-5Ee1L2J0CY4FR99iatMfvFnRj5hEw,6920
2
+ agent/planner.py,sha256=Z4IEsp9OXDF3LUuIxzvHInxoC8ypR03AS2wKTFWFvsw,207
3
+ agent/runtime.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ agent/state.py,sha256=6D-VNSNTsvQxqSdu6W5g7rbhEwJrAZpEBOTZiw1BTq8,800
5
+ app/main.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ execution/executor.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ makeless-0.1.0.dist-info/licenses/LICENSE,sha256=53aZBagQHASLcZbfl7G3ETYCOu76hZ9Vm2VHrUXGdRo,26
8
+ memory/store.py,sha256=6D-VNSNTsvQxqSdu6W5g7rbhEwJrAZpEBOTZiw1BTq8,800
9
+ observability/logger.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ security/permissions.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ tools/app_finder.py,sha256=cEjYjX2xWEXHwPdht1nqacOzwTTRxCBxt5geUTv1dY8,1890
12
+ tools/app_launcher.py,sha256=Oxr_f-lnuTpJCMuTW9Ge3R6zf8CYpK0_NcQPOyGFt1w,270
13
+ tools/builtin.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ tools/filesystem.py,sha256=IKEOeb7QT1G5uftF7AC1aA5jIsd2LuUeoUXjQMjshXU,2326
15
+ tools/indexer.py,sha256=jU4mWYiloeEnv99AfZbQPedFPZHK89QWD5VJwztO-yc,3255
16
+ tools/launcher.py,sha256=VnPVLjPBILMjfUs1kWswoy7Bcf4dtehdt9fiC95auk0,2928
17
+ tools/locations.py,sha256=5gxjRp6UvoAMiF-R5H9DDvPDgbxgCoAeBTkVTmr90sk,1323
18
+ tools/open_router.py,sha256=Fjz_ioTm_3wd9-v9rqdpQ3U3Ri2vKYzcsFh_Mj9jizw,1894
19
+ tools/opener.py,sha256=UBxDEex4qtLJhJTb-I1cJcv9JqjgBYtO17ylx3_k8zo,166
20
+ tools/reader.py,sha256=e-CVMeLiuoiTxUp3dT2kqN0Xi4MG1ca-R6omFntmw7g,1065
21
+ tools/registry.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ tools/selector.py,sha256=KQAkvTwog5jsq4X5dnZFhTvW99FMKT4oHF5HfapSN7g,1440
23
+ tools/watcher.py,sha256=g7yaUa3_w1PjYxNMEJQw3MKXLDLjvDlnD1Xpp1j_gdY,4028
24
+ makeless-0.1.0.dist-info/METADATA,sha256=Z3FO9SUpOurdbsEO8ZOdIQNuNybXurhkkngUAXJUEUc,2997
25
+ makeless-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
26
+ makeless-0.1.0.dist-info/entry_points.txt,sha256=GrYqXvpSnUViBTBl9TBSMguGWxKSf6adhOb5T_CQgJc,39
27
+ makeless-0.1.0.dist-info/top_level.txt,sha256=_s7FYukb4OBkJHzb-I3tY5KDS8ENlxS7jenlOemz83o,61
28
+ makeless-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ makeless = main:main
@@ -0,0 +1 @@
1
+ Copyright (c) 2026 Avinash
@@ -0,0 +1,8 @@
1
+ agent
2
+ app
3
+ execution
4
+ main
5
+ memory
6
+ observability
7
+ security
8
+ tools
memory/store.py ADDED
@@ -0,0 +1,40 @@
1
+
2
+ from dataclasses import dataclass, field
3
+ from enum import Enum
4
+ from typing import Any
5
+
6
+
7
+ class AgentStatus(Enum):
8
+ IDLE = "idle"
9
+ RUNNING = "running"
10
+ COMPLETED = "completed"
11
+ FAILED = "failed"
12
+ WAITING = "waiting"
13
+
14
+
15
+ class ActionType(Enum):
16
+ CALL_TOOL = "call_tool"
17
+ FINISH = "finish"
18
+
19
+
20
+ @dataclass
21
+ class AgentAction:
22
+ action_type: ActionType
23
+ tool_name: str | None = None
24
+ arguments: dict[str, Any] = field(default_factory=dict)
25
+
26
+
27
+ @dataclass
28
+ class ToolResult:
29
+ success: bool
30
+ output: Any = None
31
+ error: str | None = None
32
+
33
+
34
+ @dataclass
35
+ class AgentState:
36
+ task: str
37
+ status: AgentStatus = AgentStatus.IDLE
38
+ step_count: int = 0
39
+ max_steps: int = 10
40
+ history: list[dict[str, Any]] = field(default_factory=list)
File without changes
File without changes
tools/app_finder.py ADDED
@@ -0,0 +1,80 @@
1
+ import os
2
+
3
+
4
+ def get_start_menu_locations():
5
+ """
6
+ Return Windows Start Menu locations where application
7
+ shortcuts are commonly stored.
8
+ """
9
+
10
+ locations = []
11
+
12
+ program_data = os.environ.get("PROGRAMDATA")
13
+
14
+ if program_data:
15
+ locations.append(
16
+ os.path.join(
17
+ program_data,
18
+ "Microsoft",
19
+ "Windows",
20
+ "Start Menu",
21
+ "Programs"
22
+ )
23
+ )
24
+
25
+ app_data = os.environ.get("APPDATA")
26
+
27
+ if app_data:
28
+ locations.append(
29
+ os.path.join(
30
+ app_data,
31
+ "Microsoft",
32
+ "Windows",
33
+ "Start Menu",
34
+ "Programs"
35
+ )
36
+ )
37
+
38
+ return locations
39
+
40
+
41
+ def find_apps(query, max_results=10):
42
+ """
43
+ Search Start Menu shortcuts for installed applications.
44
+ """
45
+
46
+ query = query.casefold().strip()
47
+ results = []
48
+
49
+ if not query:
50
+ return results
51
+
52
+ for location in get_start_menu_locations():
53
+
54
+ if not os.path.exists(location):
55
+ continue
56
+
57
+ for root, directories, files in os.walk(location):
58
+
59
+ for file_name in files:
60
+
61
+ if not file_name.casefold().endswith(".lnk"):
62
+ continue
63
+
64
+ app_name = os.path.splitext(file_name)[0]
65
+
66
+ if query in app_name.casefold():
67
+ results.append(
68
+ {
69
+ "name": app_name,
70
+ "path": os.path.join(
71
+ root,
72
+ file_name
73
+ )
74
+ }
75
+ )
76
+
77
+ if len(results) >= max_results:
78
+ return results
79
+
80
+ return results
tools/app_launcher.py ADDED
@@ -0,0 +1,15 @@
1
+ import os
2
+
3
+
4
+ def launch_app(app_path):
5
+ """
6
+ Launch an application using its Windows shortcut.
7
+ """
8
+
9
+ try:
10
+ os.startfile(app_path)
11
+
12
+ return True, f"Launched {app_path}"
13
+
14
+ except OSError as error:
15
+ return False, str(error)
tools/builtin.py ADDED
File without changes