termux-dev 1.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ApvCode
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,290 @@
1
+ <div align="center">
2
+
3
+ <img src="assets/banner.svg" alt="DEVX" width="800" />
4
+
5
+ <br/><br/>
6
+
7
+ **Ultra-fast, autonomous AI pair-programmer & vibe-coding terminal agent.**
8
+ Built specifically for **Android Termux**, **Windows**, **macOS**, and **Linux**.
9
+
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
11
+ [![CI](https://github.com/apvcode/Termux-Dev/actions/workflows/ci.yml/badge.svg)](https://github.com/apvcode/Termux-Dev/actions/workflows/ci.yml)
12
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20.0.0-brightgreen.svg)](https://nodejs.org)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.4-blue.svg)](https://www.typescriptlang.org)
14
+ [![Platform](https://img.shields.io/badge/Platform-Termux%20%7C%20Windows%20%7C%20macOS%20%7C%20Linux-orange.svg)](#)
15
+
16
+ <br/>
17
+
18
+ [๐Ÿ‡ฌ๐Ÿ‡ง **English**](#-highlights) &nbsp;โ€ข&nbsp; [๐Ÿ‡ท๐Ÿ‡บ **ะ ัƒััะบะธะน**](#-ั€ัƒััะบะธะน)
19
+
20
+ <br/><br/>
21
+
22
+ <img src="assets/preview.png" alt="devx Terminal Interface" width="750" style="border-radius: 8px;" />
23
+
24
+ </div>
25
+
26
+ ---
27
+
28
+ ## ๐ŸŒŸ Highlights
29
+
30
+ - **๐Ÿง  Dual-Brain Architecture (PLAN & AGENT Modes):**
31
+ Instantly toggle between **PLAN** (safe architect, interactive requirements questionnaire, no code dumps) and **AGENT** (autonomous file edits, terminal commands, auto-installer).
32
+ - **๐Ÿš€ One-Click Plan Approval (`[๐Ÿš€ Go / โœ๏ธ Other]`):**
33
+ When an architectural plan is finalized, review and confirm with `Go` to immediately unleash the coder agent.
34
+ - **๐Ÿ–ผ๏ธ Multimodal Vision Attachments:**
35
+ Paste screenshots directly from clipboard (`/image` or `Ctrl+P`) with smart duplicate badges `[1.png 203kb]`, `[1(copy).png 421kb]`.
36
+ - **๐ŸŒ Built-in Live Web Server (`/serve`):**
37
+ Instantly preview web apps and HTML5 games on port 3000. Seamlessly opens on Android via `termux-open-url`.
38
+ - **โช Instant Snapshot Rollback (`/undo`):**
39
+ Every change made by the AI is recorded. Roll back unwanted edits cleanly with a single command.
40
+ - **๐Ÿฉบ Self-Healing Diagnostics & Auto-Installer:**
41
+ Built-in support for TypeScript (`tsc`), JavaScript (`node --check`), Python (`py_compile`), and Rust (`cargo check`). The AI automatically finds and fixes errors before finishing turns.
42
+ - **๐Ÿง  Project Memory Bank (`.devx/memory.md`):**
43
+ Persistent project context across sessions with `/memory add <rule>`.
44
+ - **๐ŸŽจ Pure Black Obsidian Theme (`#0a0a0c`):**
45
+ Deep OLED black background designed for distraction-free CLI vibe-coding.
46
+ - **๐Ÿ“œ Smart Session History (`/resume` & `/session`):**
47
+ Resume sessions with last 20 messages neatly rendered in full Markdown and track unique session IDs (`#a8f9z`).
48
+ - **โšก Universal AI Provider Support:**
49
+ **OpenRouter**, **Google Gemini**, **DeepSeek**, **Groq**, **Mistral**, **OpenAI**, **Anthropic**, **Alibaba**, and local models (**Ollama**, **LM Studio**).
50
+
51
+ ---
52
+
53
+ ## ๐Ÿ“ฆ Installation & Setup
54
+
55
+ ### Prerequisites
56
+ - **Node.js**: `v20.0.0` or higher
57
+ - **npm**, **pnpm**, or **yarn**
58
+
59
+ ### โšก Fast Global Install (Recommended)
60
+
61
+ ```bash
62
+ npm install -g termux-dev
63
+ ```
64
+
65
+ ### ๐Ÿ“ฑ Android (Termux) Setup
66
+
67
+ ```bash
68
+ # 1. Update packages & install NodeJS
69
+ pkg update && pkg install -y nodejs-lts
70
+
71
+ # 2. Install devx globally via npm
72
+ npm install -g termux-dev
73
+
74
+ # 3. Launch devx anywhere!
75
+ devx
76
+ ```
77
+
78
+ ### ๐Ÿ› ๏ธ Build from Source (Developers)
79
+
80
+ ```bash
81
+ git clone https://github.com/apvcode/Termux-Dev.git
82
+ cd Termux-Dev
83
+ npm install
84
+ npm link
85
+ ```
86
+
87
+
88
+ ---
89
+
90
+ ## ๐Ÿš€ Getting Started
91
+
92
+ Launch `devx` in any project folder:
93
+
94
+ ```bash
95
+ devx
96
+ ```
97
+
98
+ * On first run, `devx` launches an interactive setup wizard to configure your preferred AI provider and API key.
99
+ * Start directly in **PLAN mode**:
100
+ ```bash
101
+ devx --plan
102
+ ```
103
+
104
+ ---
105
+
106
+ ## โŒจ๏ธ Slash Commands
107
+
108
+ Type `/` in the prompt to open the autocomplete command palette:
109
+
110
+ | Command | Description |
111
+ | :--- | :--- |
112
+ | **`/plan`** | Switch to **PLAN** mode (architect & requirements planner) |
113
+ | **`/agent`** | Switch to **AGENT** mode (coder & autonomous executor) |
114
+ | **`/image`** | Paste image from clipboard as `[1.png 203kb]` |
115
+ | **`/serve [port]`** | Start local HTTP server for web/game preview (`/serve stop` to halt) |
116
+ | **`/memory`** | View, add (`/memory add <fact>`), or clear project memory bank |
117
+ | **`/undo`** | Revert all file changes from the last AI turn |
118
+ | **`/diff`** | View colored git diff of modified project files |
119
+ | **`/commit`** | AI-generated semantic commit message & git commit |
120
+ | **`/status`** | View git repository status |
121
+ | **`/session`** | View active session ID, stats, and metadata |
122
+ | **`/resume`** | Browse and resume saved chat sessions |
123
+ | **`/session del`** | Selectively or bulk delete saved sessions |
124
+ | **`/settings`** | Configure YOLO auto-approve, project memory, theme, and update checks |
125
+ | **`/update`** | Check and install latest updates from GitHub |
126
+ | **`/model`** | Switch model for the active provider with live search |
127
+ | **`/provider`** | Switch provider (OpenRouter, Gemini, Groq, DeepSeek, Local) |
128
+ | **`/compact`** | Compact and summarize chat context tokens |
129
+ | **`/clear`** | Clear screen and redraw banner |
130
+ | **`/init`** | Generate `AGENTS.md` developer guide in project root |
131
+ | **`/help`** | Display all available commands |
132
+ | **`/exit`** | Exit devx cleanly |
133
+
134
+ ---
135
+
136
+ ## โŒจ๏ธ Keybindings
137
+
138
+ - **`Tab`** โ€” Instantly toggle between **PLAN** and **AGENT** modes without losing your draft text.
139
+ - **`Ctrl+P`** / **`Ctrl+V`** โ€” Paste image from clipboard directly into prompt.
140
+ - **`@filename`** โ€” Fast fuzzy file autocomplete and full file embedding.
141
+ - **`Backspace`** โ€” Atomically deletes entire badges `[Pasted text #1]` and `[1.png 203kb]` in one press.
142
+ - **`Ctrl+C`** โ€” Stop current generation immediately or exit.
143
+
144
+ ---
145
+
146
+ ## โญ๏ธ Support the Project
147
+
148
+ If you find **devx** useful, please consider giving it a โญ๏ธ star on [GitHub](https://github.com/apvcode/Termux-Dev) โ€” it helps the project grow and motivates further development!
149
+
150
+ <br/>
151
+ <hr/>
152
+ <br/>
153
+
154
+ # ๐Ÿ‡ท๐Ÿ‡บ ะ ัƒััะบะธะน
155
+
156
+ ## ๐ŸŒŸ ะ“ะปะฐะฒะฝั‹ะต ะฒะพะทะผะพะถะฝะพัั‚ะธ
157
+
158
+ - **๐Ÿง  ะ”ะฒัƒั…ั€ะตะถะธะผะฝะฐั ะฐั€ั…ะธั‚ะตะบั‚ัƒั€ะฐ (PLAN ะธ AGENT):**
159
+ ะœะณะฝะพะฒะตะฝะฝะพะต ะฟะตั€ะตะบะปัŽั‡ะตะฝะธะต ะผะตะถะดัƒ **PLAN** (ะฑะตะทะพะฟะฐัะฝั‹ะน ะฐั€ั…ะธั‚ะตะบั‚ะพั€, ะธะฝั‚ะตั€ะฐะบั‚ะธะฒะฝั‹ะต ะพะฟั€ะพัะฝะธะบะธ, ะทะฐะฟั€ะตั‚ ะฝะฐ ะฝะตัะฐะฝะบั†ะธะพะฝะธั€ะพะฒะฐะฝะฝั‹ะต ะฟั€ะฐะฒะบะธ) ะธ **AGENT** (ะฐะฒั‚ะพะฝะพะผะฝะพะต ัะพะทะดะฐะฝะธะต/ั€ะตะดะฐะบั‚ะธั€ะพะฒะฐะฝะธะต ั„ะฐะนะปะพะฒ, ะฒั‹ะฟะพะปะฝะตะฝะธะต bash-ะบะพะผะฐะฝะด, ะฐะฒั‚ะพ-ัƒัั‚ะฐะฝะพะฒะบะฐ ะฟะฐะบะตั‚ะพะฒ).
160
+ - **๐Ÿš€ ะฃั‚ะฒะตั€ะถะดะตะฝะธะต ะฟะปะฐะฝะฐ ะฒ 1 ะบะปะธะบ (`[๐Ÿš€ Go / โœ๏ธ Other]`):**
161
+ ะšะพะณะดะฐ ะฐั€ั…ะธั‚ะตะบั‚ัƒั€ะฝั‹ะน ะฟะปะฐะฝ ะณะพั‚ะพะฒ, ะฟะพะดั‚ะฒะตั€ะดะธั‚ะต ะตะณะพ ะบะฝะพะฟะบะพะน `Go` โ€” ะฐะณะตะฝั‚ ะผะณะฝะพะฒะตะฝะฝะพ ะฟะตั€ะตะบะปัŽั‡ะธั‚ัั ะฒ ั€ะตะถะธะผ ะบะพะดะตั€ะฐ ะธ ะฟั€ะธัั‚ัƒะฟะธั‚ ะบ ั€ะตะฐะปะธะทะฐั†ะธะธ.
162
+ - **๐Ÿ–ผ๏ธ ะœัƒะปัŒั‚ะธะผะพะดะฐะปัŒะฝะพะต ะทั€ะตะฝะธะต ะธ ะฒัั‚ะฐะฒะบะฐ ัะบั€ะธะฝัˆะพั‚ะพะฒ:**
163
+ ะ’ัั‚ะฐะฒะปัะนั‚ะต ะธะทะพะฑั€ะฐะถะตะฝะธั ะฟั€ัะผะพ ะธะท ะฑัƒั„ะตั€ะฐ ะพะฑะผะตะฝะฐ (`/image` ะธะปะธ `Ctrl+P`) ั ะฐะฒั‚ะพ-ะฑะตะนะดะถะฐะผะธ `[1.png 203kb]`, `[1(copy).png 421kb]`.
164
+ - **๐ŸŒ ะ’ัั‚ั€ะพะตะฝะฝั‹ะน ะปะพะบะฐะปัŒะฝั‹ะน ะฒะตะฑ-ัะตั€ะฒะตั€ (`/serve`):**
165
+ ะœะณะฝะพะฒะตะฝะฝั‹ะน ะฟั€ะตะดะฟั€ะพัะผะพั‚ั€ ะฒะตะฑ-ะฟั€ะธะปะพะถะตะฝะธะน ะธ HTML5-ะธะณั€ ะฝะฐ ะฟะพั€ั‚ัƒ 3000. ะะฐ Android ะฐะฒั‚ะพะผะฐั‚ะธั‡ะตัะบะธ ะพั‚ะบั€ั‹ะฒะฐะตั‚ัั ั‡ะตั€ะตะท `termux-open-url`.
166
+ - **โช ะœะณะฝะพะฒะตะฝะฝั‹ะน ะพั‚ะบะฐั‚ ะธะทะผะตะฝะตะฝะธะน (`/undo`):**
167
+ ะšะฐะถะดะพะต ะดะตะนัั‚ะฒะธะต AI ะปะพะณะธั€ัƒะตั‚ัั ะฒ ัะฝะธะผะบะธ ัะพัั‚ะพัะฝะธั. ะ›ัŽะฑั‹ะต ะฝะตะถะตะปะฐั‚ะตะปัŒะฝั‹ะต ะฟั€ะฐะฒะบะธ ะพั‚ะผะตะฝััŽั‚ัั ะพะดะฝะพะน ะบะพะผะฐะฝะดะพะน.
168
+ - **๐Ÿฉบ ะกะฐะผะพะดะธะฐะณะฝะพัั‚ะธะบะฐ ะธ ะฐะฒั‚ะพ-ะธัะฟั€ะฐะฒะปะตะฝะธะต ะพัˆะธะฑะพะบ:**
169
+ ะ’ัั‚ั€ะพะตะฝะฝะฐั ะฟั€ะพะฒะตั€ะบะฐ ะบะพะดะฐ ะดะปั TypeScript (`tsc`), JavaScript (`node --check`), Python (`py_compile`) ะธ Rust (`cargo check`). AI ัะฐะผ ะฝะฐั…ะพะดะธั‚ ะธ ะธัะฟั€ะฐะฒะปัะตั‚ ัะธะฝั‚ะฐะบัะธั‡ะตัะบะธะต ะพัˆะธะฑะบะธ ะฟะตั€ะตะด ะทะฐะฒะตั€ัˆะตะฝะธะตะผ ะพั‚ะฒะตั‚ะฐ.
170
+ - **๐Ÿง  ะ‘ะฐะฝะบ ะฟะฐะผัั‚ะธ ะฟั€ะพะตะบั‚ะฐ (`.devx/memory.md`):**
171
+ ะ”ะพะปะณะพัั€ะพั‡ะฝะฐั ะฟะฐะผัั‚ัŒ ะฟั€ะฐะฒะธะป ะธ ะฐั€ั…ะธั‚ะตะบั‚ัƒั€ะฝั‹ั… ั€ะตัˆะตะฝะธะน ะผะตะถะดัƒ ัะตััะธัะผะธ (`/memory add <ะฟั€ะฐะฒะธะปะพ>`).
172
+ - **๐ŸŽจ ะงะธัั‚ะพ ั‡ั‘ั€ะฝะฐั ั‚ะตะผะฐ Obsidian Black (`#0a0a0c`):**
173
+ ะ“ะปัƒะฑะพะบะธะน OLED-ั‡ั‘ั€ะฝั‹ะน ั„ะพะฝ ะฒ ัั‚ะธะปะต OpenCode ะดะปั ะบะพะผั„ะพั€ั‚ะฝะพะน ะฝะพั‡ะฝะพะน ั€ะฐะทั€ะฐะฑะพั‚ะบะธ.
174
+ - **๐Ÿ“œ ะ˜ัั‚ะพั€ะธั ัะตััะธะน ั ัƒะฝะธะบะฐะปัŒะฝั‹ะผะธ ID (`/resume` ะธ `/session`):**
175
+ ะ’ะพััั‚ะฐะฝะพะฒะปะตะฝะธะต ัะตััะธะน ั ะฟั€ะตะดะฟั€ะพัะผะพั‚ั€ะพะผ ะฟะพัะปะตะดะฝะธั… 20 ัะพะพะฑั‰ะตะฝะธะน ะฒ Markdown ะธ ะบะพั€ะพั‚ะบะธะผะธ ั…ััˆ-ID (`#a8f9z`).
176
+ - **โšก ะŸะพะดะดะตั€ะถะบะฐ ะปัŽะฑั‹ั… ะฟั€ะพะฒะฐะนะดะตั€ะพะฒ:**
177
+ **OpenRouter**, **Google Gemini**, **DeepSeek**, **Groq**, **Mistral**, **OpenAI**, **Anthropic**, **Alibaba**, ะฐ ั‚ะฐะบะถะต ะปะพะบะฐะปัŒะฝั‹ะต **Ollama** ะธ **LM Studio**.
178
+
179
+ ---
180
+
181
+ ## ๐Ÿ“ฆ ะฃัั‚ะฐะฝะพะฒะบะฐ ะธ ะทะฐะฟัƒัะบ
182
+
183
+ ### ะขั€ะตะฑะพะฒะฐะฝะธั
184
+ - **Node.js**: `v20.0.0` ะธะปะธ ะฒั‹ัˆะต
185
+ - **npm**, **pnpm** ะธะปะธ **yarn**
186
+
187
+ ### โšก ะ‘ั‹ัั‚ั€ะฐั ะณะปะพะฑะฐะปัŒะฝะฐั ัƒัั‚ะฐะฝะพะฒะบะฐ (ะ ะตะบะพะผะตะฝะดัƒะตั‚ัั)
188
+
189
+ ```bash
190
+ npm install -g termux-dev
191
+ ```
192
+
193
+ ### ๐Ÿ“ฑ ะฃัั‚ะฐะฝะพะฒะบะฐ ะฝะฐ Android (Termux)
194
+
195
+ ```bash
196
+ # 1. ะžะฑะฝะพะฒะปัะตะผ ะฟะฐะบะตั‚ั‹ ะธ ัั‚ะฐะฒะธะผ NodeJS
197
+ pkg update && pkg install -y nodejs-lts
198
+
199
+ # 2. ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ devx ะณะปะพะฑะฐะปัŒะฝะพ ั‡ะตั€ะตะท npm
200
+ npm install -g termux-dev
201
+
202
+ # 3. ะ—ะฐะฟัƒัะบะฐะตะผ devx ะฒ ะปัŽะฑะพะน ะฟะฐะฟะบะต!
203
+ devx
204
+ ```
205
+
206
+ ### ๐Ÿ› ๏ธ ะกะฑะพั€ะบะฐ ะธะท ะธัั…ะพะดะฝะธะบะพะฒ (ะ”ะปั ั€ะฐะทั€ะฐะฑะพั‚ั‡ะธะบะพะฒ)
207
+
208
+ ```bash
209
+ git clone https://github.com/apvcode/Termux-Dev.git
210
+ cd Termux-Dev
211
+ npm install
212
+ npm link
213
+ ```
214
+
215
+
216
+ ---
217
+
218
+ ## ๐Ÿš€ ะะฐั‡ะฐะปะพ ั€ะฐะฑะพั‚ั‹
219
+
220
+ ะ—ะฐะฟัƒัั‚ะธั‚ะต ะบะพะผะฐะฝะดัƒ ะฒ ะฟะฐะฟะบะต ะปัŽะฑะพะณะพ ะฒะฐัˆะตะณะพ ะฟั€ะพะตะบั‚ะฐ:
221
+
222
+ ```bash
223
+ devx
224
+ ```
225
+
226
+ * ะŸั€ะธ ะฟะตั€ะฒะพะผ ะทะฐะฟัƒัะบะต ะพั‚ะบั€ะพะตั‚ัั ะผะฐัั‚ะตั€ ะฝะฐัั‚ั€ะพะนะบะธ: ะฒั‹ะฑะตั€ะธั‚ะต ะปัŽะฑะธะผะพะณะพ AI-ะฟั€ะพะฒะฐะนะดะตั€ะฐ ะธ ะฒะฒะตะดะธั‚ะต API-ะบะปัŽั‡.
227
+ * ะ—ะฐะฟัƒัะบ ัั€ะฐะทัƒ ะฒ ั€ะตะถะธะผะต ะฐั€ั…ะธั‚ะตะบั‚ะพั€ะฐ:
228
+ ```bash
229
+ devx --plan
230
+ ```
231
+
232
+ ---
233
+
234
+ ## โŒจ๏ธ ะกะปััˆ-ะบะพะผะฐะฝะดั‹
235
+
236
+ ะะฐะฟะธัˆะธั‚ะต `/` ะฒ ัั‚ั€ะพะบะต ะฒะฒะพะดะฐ, ั‡ั‚ะพะฑั‹ ะพั‚ะบั€ั‹ั‚ัŒ ะธะฝั‚ะตั€ะฐะบั‚ะธะฒะฝะพะต ะผะตะฝัŽ ะบะพะผะฐะฝะด:
237
+
238
+ | ะšะพะผะฐะฝะดะฐ | ะžะฟะธัะฐะฝะธะต |
239
+ | :--- | :--- |
240
+ | **`/plan`** | ะŸะตั€ะตะบะปัŽั‡ะธั‚ัŒัั ะฒ ั€ะตะถะธะผ ะฐั€ั…ะธั‚ะตะบั‚ะพั€ะฐ (**PLAN**) |
241
+ | **`/agent`** | ะŸะตั€ะตะบะปัŽั‡ะธั‚ัŒัั ะฒ ั€ะตะถะธะผ ะธัะฟะพะปะฝะธั‚ะตะปั (**AGENT**) |
242
+ | **`/image`** | ะ’ัั‚ะฐะฒะธั‚ัŒ ะบะฐั€ั‚ะธะฝะบัƒ ะธะท ะฑัƒั„ะตั€ะฐ ะพะฑะผะตะฝะฐ ะบะฐะบ `[1.png 203kb]` |
243
+ | **`/serve [ะฟะพั€ั‚]`** | ะ—ะฐะฟัƒัั‚ะธั‚ัŒ ะปะพะบะฐะปัŒะฝั‹ะน ะฒะตะฑ-ัะตั€ะฒะตั€ (`/serve stop` ะดะปั ะพัั‚ะฐะฝะพะฒะบะธ) |
244
+ | **`/memory`** | ะŸะพัะผะพั‚ั€ะตั‚ัŒ, ะดะพะฑะฐะฒะธั‚ัŒ (`/memory add <ั„ะฐะบั‚>`) ะธะปะธ ะพั‡ะธัั‚ะธั‚ัŒ ะฑะฐะฝะบ ะฟะฐะผัั‚ะธ |
245
+ | **`/undo`** | ะžั‚ะบะฐั‚ะธั‚ัŒ ะฒัะต ะธะทะผะตะฝะตะฝะธั ั„ะฐะนะปะพะฒ ะทะฐ ะฟะพัะปะตะดะฝะธะน ัˆะฐะณ AI |
246
+ | **`/diff`** | ะŸะพะบะฐะทะฐั‚ัŒ ั†ะฒะตั‚ะฝะพะน git diff ะธะทะผะตะฝั‘ะฝะฝั‹ั… ั„ะฐะนะปะพะฒ |
247
+ | **`/commit`** | ะกะณะตะฝะตั€ะธั€ะพะฒะฐั‚ัŒ ัะพะพะฑั‰ะตะฝะธะต ะบะพะผะผะธั‚ะฐ ั ะฟะพะผะพั‰ัŒัŽ AI ะธ ะทะฐะบะพะผะผะธั‚ะธั‚ัŒ ะฒ git |
248
+ | **`/status`** | ะŸะพะบะฐะทะฐั‚ัŒ ั‚ะตะบัƒั‰ะธะน ัั‚ะฐั‚ัƒั Git ั€ะตะฟะพะทะธั‚ะพั€ะธั |
249
+ | **`/session`** | ะŸะพะบะฐะทะฐั‚ัŒ ID, ัั‚ะฐั‚ะธัั‚ะธะบัƒ ะธ ั„ะฐะนะป ะฐะบั‚ะธะฒะฝะพะน ัะตััะธะธ |
250
+ | **`/resume`** | ะ’ั‹ะฑั€ะฐั‚ัŒ ะธ ะฒะพััั‚ะฐะฝะพะฒะธั‚ัŒ ัะพั…ั€ะฐะฝั‘ะฝะฝัƒัŽ ัะตััะธัŽ ั ะธัั‚ะพั€ะธะตะน |
251
+ | **`/session del`** | ะ’ั‹ะฑะพั€ะพั‡ะฝะพ ะธะปะธ ะฟะพะปะฝะพัั‚ัŒัŽ ัƒะดะฐะปะธั‚ัŒ ัะตััะธะธ |
252
+ | **`/settings`** | ะะฐัั‚ั€ะพะนะบะธ ะฐะฒั‚ะพ-ะฟะพะดั‚ะฒะตั€ะถะดะตะฝะธั, ะฟะฐะผัั‚ะธ, ั‚ะตะผั‹ ะธ ะฟั€ะพะฒะตั€ะบะธ ะพะฑะฝะพะฒะปะตะฝะธะน |
253
+ | **`/update`** | ะŸั€ะพะฒะตั€ะธั‚ัŒ ะธ ัƒัั‚ะฐะฝะพะฒะธั‚ัŒ ะฟะพัะปะตะดะฝะธะต ะพะฑะฝะพะฒะปะตะฝะธั ั GitHub |
254
+ | **`/model`** | ะกะผะตะฝะธั‚ัŒ ะผะพะดะตะปัŒ ั‚ะตะบัƒั‰ะตะณะพ ะฟั€ะพะฒะฐะนะดะตั€ะฐ ั ะถะธะฒั‹ะผ ะฟะพะธัะบะพะผ |
255
+ | **`/provider`** | ะกะผะตะฝะธั‚ัŒ AI-ะฟั€ะพะฒะฐะนะดะตั€ะฐ (OpenRouter, Gemini, Groq, DeepSeek, Local) |
256
+ | **`/compact`** | ะกะถะฐั‚ัŒ ะบะพะฝั‚ะตะบัั‚ ะดะธะฐะปะพะณะฐ ะดะปั ัะบะพะฝะพะผะธะธ ั‚ะพะบะตะฝะพะฒ |
257
+ | **`/clear`** | ะžั‡ะธัั‚ะธั‚ัŒ ัะบั€ะฐะฝ ั‚ะตั€ะผะธะฝะฐะปะฐ ะธ ะฟะตั€ะตั€ะธัะพะฒะฐั‚ัŒ ะฑะฐะฝะฝะตั€ |
258
+ | **`/init`** | ะกะพะทะดะฐั‚ัŒ ั„ะฐะนะป ะธะฝัั‚ั€ัƒะบั†ะธะน `AGENTS.md` ะฒ ะบะพั€ะฝะต ะฟั€ะพะตะบั‚ะฐ |
259
+ | **`/help`** | ะŸะพะบะฐะทะฐั‚ัŒ ัะฟะธัะพะบ ะฒัะตั… ะดะพัั‚ัƒะฟะฝั‹ั… ะบะพะผะฐะฝะด |
260
+ | **`/exit`** | ะ—ะฐะฒะตั€ัˆะธั‚ัŒ ั€ะฐะฑะพั‚ัƒ devx |
261
+
262
+ ---
263
+
264
+ ## โŒจ๏ธ ะ“ะพั€ัั‡ะธะต ะบะปะฐะฒะธัˆะธ
265
+
266
+ - **`Tab`** โ€” ะœะณะฝะพะฒะตะฝะฝะพะต ะฟะตั€ะตะบะปัŽั‡ะตะฝะธะต ะผะตะถะดัƒ ั€ะตะถะธะผะฐะผะธ **PLAN** ะธ **AGENT** ะฑะตะท ะฟะพั‚ะตั€ะธ ะฝะฐะฑั€ะฐะฝะฝะพะณะพ ั‚ะตะบัั‚ะฐ.
267
+ - **`Ctrl+P`** / **`Ctrl+V`** โ€” ะ’ัั‚ะฐะฒะบะฐ ัะบั€ะธะฝัˆะพั‚ะฐ/ะบะฐั€ั‚ะธะฝะบะธ ะธะท ะฑัƒั„ะตั€ะฐ ะพะฑะผะตะฝะฐ.
268
+ - **`@ั„ะฐะนะป`** โ€” ะฃะผะฝะพะต ะฐะฒั‚ะพะดะพะฟะพะปะฝะตะฝะธะต ั„ะฐะนะปะพะฒ ะธ ะฟั€ะธะบั€ะตะฟะปะตะฝะธะต ะธั… ัะพะดะตั€ะถะธะผะพะณะพ ะบ ะทะฐะฟั€ะพััƒ.
269
+ - **`Backspace`** โ€” ะั‚ะพะผะฐั€ะฝะพะต ัƒะดะฐะปะตะฝะธะต ะฑะตะนะดะถะตะน `[Pasted text #1]` ะธ `[1.png 203kb]` ะทะฐ ะพะดะฝะพ ะฝะฐะถะฐั‚ะธะต.
270
+ - **`Ctrl+C`** โ€” ะœะณะฝะพะฒะตะฝะฝะฐั ะพัั‚ะฐะฝะพะฒะบะฐ ะณะตะฝะตั€ะฐั†ะธะธ ะพั‚ะฒะตั‚ะฐ ะธะปะธ ะฒั‹ั…ะพะด.
271
+
272
+ ---
273
+
274
+ ## โญ๏ธ ะŸะพะดะดะตั€ะถะธั‚ะต ะฟั€ะพะตะบั‚
275
+
276
+ ะ•ัะปะธ ะฒะฐะผ ะฟะพะฝั€ะฐะฒะธะปัั **devx**, ะฟะพะถะฐะปัƒะนัั‚ะฐ, ะฟะพัั‚ะฐะฒัŒั‚ะต โญ๏ธ ะทะฒั‘ะทะดะพั‡ะบัƒ ะฝะฐ [GitHub](https://github.com/apvcode/Termux-Dev) โ€” ัั‚ะพ ะฟะพะผะพะณะฐะตั‚ ะฟั€ะพะตะบั‚ัƒ ั€ะฐัั‚ะธ ะธ ะผะพั‚ะธะฒะธั€ัƒะตั‚ ะดะพะฑะฐะฒะปัั‚ัŒ ะฝะพะฒั‹ะต ะบั€ัƒั‚ั‹ะต ะฒะพะทะผะพะถะฝะพัั‚ะธ!
277
+
278
+ ---
279
+
280
+ ## ๐Ÿ“„ License
281
+
282
+ This project is licensed under the [MIT License](LICENSE).
283
+
284
+ ---
285
+
286
+ <div align="center">
287
+
288
+ Made with โค๏ธ by [ApvCode](https://github.com/ApvCode) for developers, vibe-coders, and Termux hackers.
289
+
290
+ </div>
@@ -0,0 +1,33 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 850 180" width="100%" height="180">
2
+ <defs>
3
+ <linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" stop-color="#0a0a0c"/>
5
+ <stop offset="100%" stop-color="#111116"/>
6
+ </linearGradient>
7
+ <linearGradient id="cyanGrad" x1="0%" y1="0%" x2="100%" y2="0%">
8
+ <stop offset="0%" stop-color="#00f2fe"/>
9
+ <stop offset="50%" stop-color="#4facfe"/>
10
+ <stop offset="100%" stop-color="#00f2fe"/>
11
+ </linearGradient>
12
+ <filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
13
+ <feGaussianBlur stdDeviation="5" result="blur" />
14
+ <feComposite in="SourceGraphic" in2="blur" operator="over" />
15
+ </filter>
16
+ </defs>
17
+
18
+ <!-- Container Box -->
19
+ <rect x="2" y="2" width="846" height="176" rx="12" fill="url(#bgGrad)" stroke="#22222c" stroke-width="1.5"/>
20
+
21
+ <!-- Logo Text DEVX -->
22
+ <g filter="url(#glow)">
23
+ <text x="425" y="105" font-family="'Courier New', 'Consolas', 'Fira Code', monospace" font-size="78" font-weight="900" fill="url(#cyanGrad)" text-anchor="middle" letter-spacing="12">DEVX</text>
24
+ </g>
25
+
26
+ <!-- Tagline & Badge -->
27
+ <text x="425" y="142" font-family="system-ui, -apple-system, sans-serif" font-size="14" font-weight="600" fill="#8b949e" text-anchor="middle" letter-spacing="3">
28
+ THE TERMINAL-NATIVE AI CODING AGENT <tspan fill="#00f2fe" font-weight="bold">v1.0.2</tspan>
29
+ </text>
30
+
31
+ <!-- Top Accent Line -->
32
+ <rect x="325" y="12" width="200" height="2" rx="1" fill="url(#cyanGrad)" opacity="0.8"/>
33
+ </svg>
Binary file
package/bin/devx.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/cli/index.js';
@@ -0,0 +1,136 @@
1
+ import fs from 'fs/promises';
2
+ import fsSync from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { exec } from 'child_process';
6
+ const MEDIA_DIR = path.join(process.cwd(), '.devx', 'media');
7
+ export function formatFileSize(bytes) {
8
+ if (bytes < 1024)
9
+ return `${bytes}b`;
10
+ const kb = Math.round(bytes / 1024);
11
+ if (kb < 1024)
12
+ return `${kb}kb`;
13
+ const mb = (bytes / (1024 * 1024)).toFixed(1);
14
+ return `${mb}mb`;
15
+ }
16
+ export function getUniqueImageName(baseName, existingNames) {
17
+ if (!existingNames.has(baseName)) {
18
+ return baseName;
19
+ }
20
+ const ext = path.extname(baseName);
21
+ const nameWithoutExt = path.basename(baseName, ext);
22
+ let copyIndex = 1;
23
+ while (true) {
24
+ const candidate = copyIndex === 1
25
+ ? `${nameWithoutExt}(copy)${ext}`
26
+ : `${nameWithoutExt}(copy ${copyIndex})${ext}`;
27
+ if (!existingNames.has(candidate)) {
28
+ return candidate;
29
+ }
30
+ copyIndex++;
31
+ }
32
+ }
33
+ export async function saveClipboardImage(preferredName = 'image.png', existingNames) {
34
+ if (!fsSync.existsSync(MEDIA_DIR)) {
35
+ await fs.mkdir(MEDIA_DIR, { recursive: true });
36
+ }
37
+ const uniqueName = getUniqueImageName(preferredName, existingNames);
38
+ const targetPath = path.join(MEDIA_DIR, uniqueName);
39
+ return new Promise((resolve) => {
40
+ const isWindows = os.platform() === 'win32';
41
+ const isMac = os.platform() === 'darwin';
42
+ if (isWindows) {
43
+ const psScript = `
44
+ Add-Type -AssemblyName System.Windows.Forms
45
+ Add-Type -AssemblyName System.Drawing
46
+ $img = [System.Windows.Forms.Clipboard]::GetImage()
47
+ if ($img -ne $null) {
48
+ $img.Save('${targetPath.replace(/\\/g, '\\\\')}', [System.Drawing.Imaging.ImageFormat]::Png)
49
+ Write-Output "SAVED"
50
+ } else {
51
+ Write-Output "NO_IMAGE"
52
+ }
53
+ `;
54
+ const b64 = Buffer.from(psScript, 'utf16le').toString('base64');
55
+ exec(`powershell.exe -NoProfile -NonInteractive -EncodedCommand ${b64}`, (err, stdout) => {
56
+ if (!err && stdout.includes('SAVED') && fsSync.existsSync(targetPath)) {
57
+ const stat = fsSync.statSync(targetPath);
58
+ resolve({
59
+ fileName: uniqueName,
60
+ filePath: targetPath,
61
+ size: stat.size,
62
+ sizeStr: formatFileSize(stat.size)
63
+ });
64
+ }
65
+ else {
66
+ resolve(null);
67
+ }
68
+ });
69
+ }
70
+ else if (isMac) {
71
+ exec(`pngpaste "${targetPath}"`, (err) => {
72
+ if (!err && fsSync.existsSync(targetPath)) {
73
+ const stat = fsSync.statSync(targetPath);
74
+ resolve({
75
+ fileName: uniqueName,
76
+ filePath: targetPath,
77
+ size: stat.size,
78
+ sizeStr: formatFileSize(stat.size)
79
+ });
80
+ }
81
+ else {
82
+ resolve(null);
83
+ }
84
+ });
85
+ }
86
+ else {
87
+ // Linux / Termux: try xclip / wl-paste
88
+ exec(`xclip -selection clipboard -t image/png -o > "${targetPath}" 2>/dev/null || wl-paste -t image/png > "${targetPath}" 2>/dev/null`, () => {
89
+ if (fsSync.existsSync(targetPath)) {
90
+ const stat = fsSync.statSync(targetPath);
91
+ if (stat.size > 100) {
92
+ return resolve({
93
+ fileName: uniqueName,
94
+ filePath: targetPath,
95
+ size: stat.size,
96
+ sizeStr: formatFileSize(stat.size)
97
+ });
98
+ }
99
+ try {
100
+ fsSync.unlinkSync(targetPath);
101
+ }
102
+ catch { }
103
+ }
104
+ resolve(null);
105
+ });
106
+ }
107
+ });
108
+ }
109
+ export async function processPastedFilePath(rawPath, existingNames) {
110
+ const cleanPath = rawPath.trim().replace(/^['"&]+|['"]+$/g, '').trim();
111
+ const resolved = path.resolve(process.cwd(), cleanPath);
112
+ const imageExts = new Set(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg', '.bmp']);
113
+ const ext = path.extname(resolved).toLowerCase();
114
+ if (imageExts.has(ext) && fsSync.existsSync(resolved)) {
115
+ try {
116
+ const stat = fsSync.statSync(resolved);
117
+ if (stat.isFile()) {
118
+ const baseName = path.basename(resolved);
119
+ const uniqueName = getUniqueImageName(baseName, existingNames);
120
+ if (!fsSync.existsSync(MEDIA_DIR)) {
121
+ await fs.mkdir(MEDIA_DIR, { recursive: true });
122
+ }
123
+ const targetPath = path.join(MEDIA_DIR, uniqueName);
124
+ await fs.copyFile(resolved, targetPath);
125
+ return {
126
+ fileName: uniqueName,
127
+ filePath: targetPath,
128
+ size: stat.size,
129
+ sizeStr: formatFileSize(stat.size)
130
+ };
131
+ }
132
+ }
133
+ catch { }
134
+ }
135
+ return null;
136
+ }
@@ -0,0 +1,93 @@
1
+ import fs from 'fs/promises';
2
+ import fsSync from 'fs';
3
+ import path from 'path';
4
+ const IGNORED_NAMES = new Set([
5
+ 'node_modules',
6
+ '.git',
7
+ '.next',
8
+ 'dist',
9
+ 'build',
10
+ 'coverage',
11
+ '.turbo',
12
+ '.cache',
13
+ 'vendor',
14
+ '.tempmediaStorage'
15
+ ]);
16
+ let cachedFiles = [];
17
+ let lastScanTime = 0;
18
+ export async function scanProjectFiles(force = false) {
19
+ const now = Date.now();
20
+ if (!force && cachedFiles.length > 0 && (now - lastScanTime < 5000)) {
21
+ return cachedFiles;
22
+ }
23
+ const results = [];
24
+ async function walk(dir, depth = 0) {
25
+ if (depth > 6 || results.length > 300)
26
+ return;
27
+ try {
28
+ const entries = await fs.readdir(dir, { withFileTypes: true });
29
+ for (const entry of entries) {
30
+ if (entry.name.startsWith('.') && entry.name !== '.env')
31
+ continue;
32
+ if (IGNORED_NAMES.has(entry.name))
33
+ continue;
34
+ const fullPath = path.join(dir, entry.name);
35
+ const rel = path.relative(process.cwd(), fullPath).replace(/\\/g, '/');
36
+ if (entry.isDirectory()) {
37
+ results.push(`${rel}/`);
38
+ await walk(fullPath, depth + 1);
39
+ }
40
+ else if (entry.isFile()) {
41
+ results.push(rel);
42
+ }
43
+ }
44
+ }
45
+ catch { }
46
+ }
47
+ await walk(process.cwd());
48
+ cachedFiles = results;
49
+ lastScanTime = now;
50
+ return results;
51
+ }
52
+ const IMAGE_EXTS = {
53
+ '.png': 'image/png',
54
+ '.jpg': 'image/jpeg',
55
+ '.jpeg': 'image/jpeg',
56
+ '.webp': 'image/webp',
57
+ '.gif': 'image/gif',
58
+ '.svg': 'image/svg+xml'
59
+ };
60
+ export async function resolveAtMentions(text) {
61
+ const mentionRegex = /@([a-zA-Z0-9_\-./]+)/g;
62
+ const attachments = [];
63
+ const images = [];
64
+ const seenPaths = new Set();
65
+ let match;
66
+ while ((match = mentionRegex.exec(text)) !== null) {
67
+ const rawPath = match[1];
68
+ const resolved = path.resolve(process.cwd(), rawPath);
69
+ if (seenPaths.has(resolved))
70
+ continue;
71
+ seenPaths.add(resolved);
72
+ if (fsSync.existsSync(resolved)) {
73
+ try {
74
+ const stat = fsSync.statSync(resolved);
75
+ const ext = path.extname(resolved).toLowerCase();
76
+ if (stat.isFile()) {
77
+ if (IMAGE_EXTS[ext]) {
78
+ const buf = await fs.readFile(resolved);
79
+ const b64 = buf.toString('base64');
80
+ const dataUrl = `data:${IMAGE_EXTS[ext]};base64,${b64}`;
81
+ images.push({ path: rawPath, dataUrl });
82
+ }
83
+ else if (stat.size < 50000) {
84
+ const content = await fs.readFile(resolved, 'utf8');
85
+ attachments.push({ path: rawPath, content });
86
+ }
87
+ }
88
+ }
89
+ catch { }
90
+ }
91
+ }
92
+ return { text, attachments, images };
93
+ }